可以0.999 ...乘以时舍入为1?

时间:2012-04-27 20:57:02

标签: java actionscript-3 math floating-point

将非常接近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中也不会出错,因为一位同事报告说他看到它出错了,这部分促使我提出这个问题

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

在java中使用Math.random(http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Math.html),该值可以大于或等于0.0且小于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返回的值。您可以测试运行示例代码

答案 2 :(得分: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
}