Bar*_*lom 35 java math floating-point actionscript-3
当将非常接近1的浮点数乘以int> 0时,它是否可以解释为1.
也就是说,如果Math.random()返回其最高可能结果(比1.0低1步),将会
(int)(Math.random() * 8)
Run Code Online (Sandbox Code Playgroud)
是8还是7?
对于一个实际的例子,这个经常使用的构造是否可以提供索引超出范围的错误:
someArray[(int)(Math.random() * someArray.length)];
Run Code Online (Sandbox Code Playgroud)
我对Java和ActionScript 3的答案特别感兴趣,但我想它们都使用相同的浮点运算规则,任何平台的答案都会很有用.
更新:虽然我已经接受了答案,但我仍然感谢确认这在ActionScript 3中也不会出错,因为一位同事报告说他看到它出错了,这部分促使我提出这个问题.
aio*_*obe 45
如果将1.0以下的最大值乘以someInt(> 0),结果将永远不会someInt.
这可以对这样的整数进行详尽的测试:
Double greatestLessThanOne = Double.longBitsToDouble(4607182418800017407L);
// Assert that greatestLessThanOne is indeed the largest double less than 1.
//assert 1.0 == greatestLessThanOne + Math.ulp(greatestLessThanOne);
for (int i = 1; i >= 0; i++)
if ((int) (greatestLessThanOne * i) == i)
System.out.println("Exception found: " + i);
Run Code Online (Sandbox Code Playgroud)
该代码段不产生任何输出.
(Math.ulp返回给定double和double值之间的距离,接下来是幅度更大.断言因此确保它greatestLessThanOne确实是小于1.0的最大值.)
换句话说,你的路线
Object element = elementArray[(int)(Math.random() * elementArray.length)];
Run Code Online (Sandbox Code Playgroud)
永远不会产生ArrayIndexOutOfBoundsException.
此外,根据Mark Dickinsons在这里的评论,这也适用于乘以双倍.
使用围绕最接近模式的IEEE 754浮点运算,您可以显示
x * y <任意x < 1.0和任何非微小正数的yy.(如果y是次正规或最小的正正常数,它可能会失败.)