【发布时间】:2011-12-06 15:35:49
【问题描述】:
以下内容无法编译:
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 的双精度数,并且当添加到整数时,小数部分将是由于精度损失而丢失。运行以下代码,看到意外的结果:
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 等。
为什么?
顺便说一句……这不是在任何地方都可以使用的代码,它来自我在时事通讯中收到的一个测验。嵌套循环的原因是我可以间隔查看结果的值。
【问题讨论】:
-
这个问题在一般情况下已经多次回答了。
-
写
for (int i = 0; i < 42000000; i ++)的奇怪方式 -
先尝试将 Math.random() 调用转换为整数。目前,您的代码中的 '1' 文字被隐式转换为双精度数,这意味着在某处丢失了精度。
-
float vs. double precision 的可能重复项
-
@Woot4Moo 不是吗?整数的最大值(在 java 中)是 2,147,483,647。那是 4200 万的 50 倍。