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 中也不会出错,因为一位同事报告说他曾经看到它出错是部分促使我提出这个问题的原因。

4

3 回答 3

1

因为 8 是 2 的幂,所以将浮点数乘以它永远不会增加或删除值的精度,除非溢出。乘以其他数字,特别是浮点数(除了 2 的负幂,例如 0.25、0.0625 等),会降低精度。

于 2012-04-27T21:03:08.773 回答
0

在 java (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html) 中使用 Math.random,该值可以大于或等于 0.0 且小于 1.0。

使用值为 0.999999 的测试, (int)(Math.random() * 8) 的值为 8。您可以使用下一个代码测试实验

public static void main(String args[]) {
        for (int i = 0; i <= 100; i++) {
            double frac1=0.999999999999999999 ;
            double frac=Math.random() ;
            int integer=(int) (frac*8);
            int integer1=(int) (frac1*8);
            System.out.println( integer+"-"+frac);
            System.out.println( integer1+"-"+frac);
        }
    }

但是 Math.random()*8 可以返回其他值,例如 1、2、3、4、5、7 或 6,这取决于 Math.random 返回的值。您可以运行示例代码对此进行测试

于 2012-04-27T21:14:35.750 回答
0

实际上,快速详尽的搜索可以表明对于任何具有浮点数的 32 位整数都不会发生这种情况:

public static void main(String[] args) {
    int repr = Float.floatToIntBits(1f) - 1;
    float val = Float.intBitsToFloat(repr);
    for (long i = 1; i <= -(long)Integer.MIN_VALUE; i++) {
        if ((int) (val * i) == i) {
            System.out.println("FOUND VALUE: " + i);
        }
        if ((int) (val * -i) == -i) {
            System.out.println("FOUND VALUE: " + -i);
        }
        if (i % 100000000 == 0) {
            System.out.println("Done: " + (double)i/Integer.MAX_VALUE);
        }
    }
    // nothing printed
}
于 2012-04-27T22:15:56.827 回答