乘以0.99999999999是否可以舍入到1.0?

当将一个非常接近1的浮点数与int> 0相乘时,它是否可以解释为1。

也就是说,如果Math.random()返回可能的最高结果(即1.0以下的1步),将会

 (int)(Math.random() * 8) 

是8还是7?

举一个实际的例子,这个经常使用的结构可以给出一个索引越界的错误:

 someArray[(int)(Math.random() * someArray.length)]; 

我特别感兴趣的Java和ActionScript 3的答案,但我想他们都使用相同的规则浮点运算,任何平台的答案将是有用的。

更新 :虽然我已经接受了一个答案,但是我还是希望证实这个在ActionScript 3中不会出错,因为一个同事报告他看到它出错一次是什么部分促使我问这个问题。

如果用someInt (> 0)乘以1.0以下的someInt ,结果永远不会是someInt

这可以穷举testing这样的整数:

 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); 

片段不产生输出。

Math.ulp返回给定的double和double值之间的距离,其次是更大的值,因此这个断言保证了greatestLessThanOne Math.ulp确实是小于1.0的最大值)。

换句话说,你的路线

 Object element = elementArray[(int)(Math.random() * elementArray.length)]; 

将永远不会引发ArrayIndexOutOfBoundsException。


此外,根据马克·迪金森在这里的评论,这也成立了倍增倍数。

在IEEE 754浮点运算处于最接近的模式下,可以显示任何x < 1.0和任何非微小正y x * y < y 。 (如果y是低于正常值或是正常的最小正数,则可能失败。)

围绕它,可能是这样的:

 BigDecimal bd = new BigDecimal(Double.toString(d)); bd = bd.setScale(decimalPlace,BigDecimal.ROUND_HALF_UP);