当前位置: 首页 > 知识库问答 >
问题:

Java For loop在更改循环变量类型时更改数值结果

幸经艺
2023-03-14

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

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

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

共有3个答案

薛烨
2023-03-14

2*ii接近循环结束时,int的最大值将溢出,该值为2147483647。

使用长操作不会溢出。

正确的程序是使用长字体。可能是因为对于某些奇怪的行为,在正确的PI附近添加和删除值,溢出会立即计算到更接近正确PI的值。

我认为改变for循环的限制值很少会将最终结果更改为离右PI更远的值。

南门欣怡
2023-03-14

因为你在排队的时候被挤满了

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

其中2*i的值与最大整数值交叉

int范围是-2147483648到2147483647,但如果2*i的值越大,它就会跨越该范围。

最好坚持使用long,这会给你正确的输出。

燕钟展
2023-03-14

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

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

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

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

 类似资料:
  • 我正在研究一个涉及for循环和if-else语句的java函数。我需要根据多次迭代中的条件更改标志变量的值。我声明了一个名为flag的变量,并希望根据每次迭代中的条件进行更改。我需要在每次迭代结束时打印flag变量的值。但是当我打印变量时,它显示了一个错误,变量没有初始化。如果我给它一个初始值,它会一直打印初始值,而不是在If-else语句中处理的值。我不能根据自己的要求初始化for循环中的fla

  • 我在android和Kotlin有奇怪的问题。问题是我用类型定义变量,但在运行时更改为 我这样定义我的变量: 我使用kotlin 1.3.71和jvm 1.8。 更新0:

  • 问题内容: 我了解的这段代码。我们复制A并将其称为C。当A更改时,C保持不变 但是当A是一个数组时,我们会有不同的情景。C不仅会改变,而且甚至在我们碰到A之前都会改变 有人可以解释第二个示例中发生的情况吗? 问题答案: Pointy的答案有很好的信息,但这不是此问题的正确答案。 OP所描述的行为是一个错误的一部分,该错误于2010年3月首次报告,并于2012年8月为Webkit进行了修补,但截至本

  • 如何显示一个计数器从1到2到3再到n的按钮点击。我尝试在for循环中执行setState,但不起作用。我知道React的setState是异步的,我甚至尝试过使用prevState,但它不起作用。 https://www.webpackbin.com/bins/-kku1nja-ectflydgf_s 我想把计数从0增加到n,作为点击时的定时器。

  • 我正在使用Android Studio创建一个应用程序,并使用Firebase模拟后端数据库。目前,我正在尝试使应用程序能够接收并显示我通过Firebase输入的数据。当我使用Firebase data snapshot方法捕获数据时,由于快照发生在内部类中,我无法保存和使用数据。 例如,在Firebase中,我已将“Fri”的值指定给“2步”。如果您查看下面的代码,第一条print语句(内部类内

  • 我在php中工作,现在我正在将时循环应用于我的代码。我正在从数据库中获取数据。现在我必须将该数据应用于页面中的一个Div。 我的问题是"div类="项目活动"在循环中每次活动类都需要。现在我想改变它,就像在第一个循环过程之后,当第二个开始时,我想把那个div改变成这个"div类="项目"。 我对这个循环过程不太熟悉,所以我无法解决这个问题。需要帮助。谢谢