我目前正在进行预微积分,并认为我会制作一个快速程序,它会给我阶乘10的结果.在测试它时,我注意到我在第5次迭代后得到的结果不正确.但是,前4次迭代是正确的.
public class Factorial
{
public static void main(String[] args)
{
int x = 1;
int factorial;
for(int n = 10; n!=1; n--)
{
factorial = n*(n-1);
x = x * factorial;
System.out.printf("%d ", x);
}
}//end of class main
}//end of class factorial
Run Code Online (Sandbox Code Playgroud)

这是一个整数溢出问题.使用long或unsigned long代替int.(正如@Dunes建议的那样,你最好的选择是BigInteger使用非常大的数字,因为理论上它永远不会溢出)
基本思想是signed int存储数字之间的数字-2,147,483,648 to 2,147,483,647,存储为二进制位(计算机中的所有信息都存储为1's和0's)
正数0以最高有效位存储,负数1以最高有效位存储.如果正数在二进制表示中变得太大,则数字将转移到有符号位并将正数转换为负数的二进制表示.
然后当阶乘比甚至unsigned int可以存储的东西更大时,它将"环绕"并从最重要的(有符号)位丢失结转 - 这就是为什么你看到有时候交替出现正负值的模式输出.
你超过了这种int类型的容量(2,147,483,647),所以你的结果会回到最小值int.请尝试使用long.
说到这一点,你目前使用的方法不会得到正确的答案:实际上,你正在计算10! ^ 2.
为什么复杂的事情?您可以轻松地执行以下操作:
long x = 1L;
for(int n = 1; n < 10; n++)
{
x *= n;
System.out.println(x);
}
Run Code Online (Sandbox Code Playgroud)
1 2 6 24 120 720 5040 40320 362880
显示连续因子,直到10!达到.
此外,正如其他人所提到的,如果您需要的值大于long您应该使用的值BigInteger,则支持任意精度.
| 归档时间: |
|
| 查看次数: |
778 次 |
| 最近记录: |