Java For循环在更改循环variables的types时更改数字结果

我写了一个程序,用莱布尼茨公式计算PI数字:

[ 莱布尼茨公式]

我写了一个初始化types为“int”的for循环,循环工作正常,但是当我将初始化types更改为“long”时,结果被更改。 这只发生在循环时间超过十亿时。 这使得“int-loop”计算PI比“long-loop”更精确。 我不知道为什么会发生这种情况。 请帮我理解这个问题。 谢谢! 这是我的代码。

public static void main(String[] args) { double result1 = 0; double result2 = 0; double sign = 1; for (int i = 0; i <= 1607702095; i++) { result1 += sign/(2 * i + 1); sign *= -1; } sign = 1; for (long j = 0; j <= 1607702095; j++) { result2 += sign/(2 * j + 1); sign *= -1; } System.out.println("result1 " + result1 * 4); System.out.println("result2 " + result2 * 4); System.out.println("pi " + Math.PI); } 

结果是:

 result1 3.141592653576877 result2 3.1415926529660116 pi 3.141592653589793 

实际上,当i足够大时,你的第一个循环在(2 * i + 1)的计算中会有int溢出,所以我不会依赖它的输出。

另一方面,第二个循环产生更正确的输出,因为(2 * j + 1)不会溢出,因为它执行long乘法。

这使“int-loop”计算PI比“long-loop”更精确,

这可能只是一个巧合,因为int循环中的计算溢出。

因为你在线上溢出

 result1 += sign/(2 * i + 1); 

2*i的值越过最大整数值

int范围是-2,147,483,648 to 2,147,483,647但是当你为了更大的值而做2*i ,它会跨越这个范围。

最好坚持long并给你正确的输出。

2 * i当我接近你的循环结束溢出的最大整数值2147483647

长时间使用该操作不会溢出。

正确的过程是使用一个长types。 可能是因为在正确的PI周围添加和删除了一些奇怪行为的值,溢出会瞬间计算到更接近正确PI的值。

我认为改变less数值的for循环的极限会将最终的结果改变为离正确的PI更远的值。

你有整数溢出

有符号整数的最大容量是(2 ^ 31)-1或2,147,483,647。

(1,607,702,095 * 2)为3215404190,大于2,147,483,647。

当你改变我很久,你增加我的能力(2 ^ 63)-1。

注意到每个人都指向整数溢出,但你可能需要一个解决scheme。 (如果你已经有一个,请忽略以下:))

在代码的(2 * i + 1)部分溢出,您应该将for循环中的i最大值设置为(Integer.MAX_VALUE / 2 - 1) ,这会导致:

 for (int i = 0; i <= (Integer.MAX_VALUE / 2 - 1); i++) { result1 += sign/(2 * i + 1); sign *= -1; } 

你也可以通过(Long.MAX_VALUE / 2 - 1)长时间做这个事情,但是它会运行很长时间。