gpt4 book ai didi

java - Math.random() 和精度损失的好奇心

转载 作者:搜寻专家 更新时间:2023-11-01 01:18:25 25 4
gpt4 key购买 nike

以下不编译:

int result = Math.random() + 1;

error: possible loss of precision
int result = Math.random() + 1;
^
required: int
found: double

但以下确实编译:

int result = 0;
result += Math.random() + 1;

为什么?

将可编译代码放入嵌套循环中,人们会期望结果在每次迭代中递增 1,因为 Math.random() 总是返回一个值小于 1 的 double 值,并且当与整数相加时,小数部分将是由于精度损失而丢失。运行以下代码并看到意想不到的结果:

public class MathRandomCuriosity
{
public static void main(String[] args)
{
int result = 0;
for (int i = 0; i < 10; i++)
{
// System.out.println(result);
for (int j = 0; j < 20; j++)
{
// System.out.println(result);
for (int k = 0; k < 300; k++)
{
// System.out.println(result);
for (int m = 0; m < 7000; m++)
{
result += Math.random() + 1;
}
}
}
}
System.out.println(result);
}
}

对于 10*20*300*7000 = 42,000,000 次迭代,结果应为 42,000,000。但事实并非如此!结果各不相同,即 42,000,007 与 42,000,006 与 42,000,010 等。

为什么?

顺便说一下...这不是任何地方都在使用的代码,它来 self 在时事通讯中收到的一个测验。嵌套循环的原因是我可以每隔一段时间查看结果的值。

最佳答案

+= 等赋值运算符会进行隐式转换。

注意:在这种情况下,Math.random() 每次都会向下舍入为 0,这会严重降低精度。 ;)

但是 Math.random() + 1 有很小的机会四舍五入为 2。例如1.999999 将四舍五入为 1,但 1.9999999999999999 将四舍五入为 2(但 double + 运算符而不是转换为 int)。

long l = Double.doubleToLongBits(1.0);
double d0_999etc = Double.longBitsToDouble(l -1);
System.out.println("The value before 1 is " +d0_999etc+" cast to (int) is "+ (int) d0_999etc);
System.out.println("The value before 1, plus 1 is " +(1+d0_999etc)+" cast to (int) is "+(int)(1 +d0_999etc));

打印

The value before 1 is 0.9999999999999999 cast to (int) is 0
The value before 1, plus 1 is 2.0 cast to (int) is 2

关于java - Math.random() 和精度损失的好奇心,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8402500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com