以下内容无法编译:
int result = Math.random() + 1;
error: possible loss of precision
int result = Math.random() + 1;
^
required: int
found: double
Run Code Online (Sandbox Code Playgroud)
但下面不会编译:
int result = 0;
result += Math.random() + 1;
Run Code Online (Sandbox Code Playgroud)
为什么?
将可编译代码放入嵌套循环中,可以预期每次迭代时结果都会递增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);
}
}
Run Code Online (Sandbox Code Playgroud)
使用10*20*300*7000 = 42,000,000次迭代,结果应为42,000,000.但事实并非如此!结果有所不同,即42,000,007 vs. 42,000,006 vs. 42,000,010等.
为什么?
顺便说一句......这不是在任何地方使用的代码,而是来自我在简报中收到的测验.嵌套循环的原因是我可以间隔查看结果的值.
Pet*_*rey 12
分配的运算符就像+=
隐式转换一样.
注意:在这种情况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));
Run Code Online (Sandbox Code Playgroud)
版画
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2336 次 |
最近记录: |