0.99999999999 相乘时可以四舍五入为 1.0 吗? [英] Can 0.99999999999 be rounded to 1.0 when multiplying?

查看:16
本文介绍了0.99999999999 相乘时可以四舍五入为 1.0 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个非常接近于 1 的浮点数乘以一个 int > 0 时,它可以被解释为 1.

When multiplying a floating point number that is very close to 1 with an int > 0, can it ever be interpreted as 1.

也就是说,如果 Math.random() 返回其可能的最高结果(比 1.0 低 1 步),将

That is, if Math.random() returns its highest possible result (which is 1 step below 1.0), will

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

是 8 还是 7?

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

For a practical example, can this often-used construct give an index out of bounds error:

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

我对 Java 和 ActionScript 3 的答案特别感兴趣,但我想它们都使用相同的浮点运算规则,并且适用于任何平台的答案都会有用.

I'm specifically interested in answers for Java and ActionScript 3, but I suppose they all use the same rules for floating point arithmetic, and answers for any platform would be useful.

更新:虽然我已经接受了一个答案,但我仍然希望确认这在 ActionScript 3 中也不会出错,因为一位同事报告说他曾经看到它出错了部分原因促使我提出这个问题.

Update: Though I already accepted an answer, I'd still appreciate confirmation that this can't go wrong in ActionScript 3 either, since a colleague reporting that he saw it go wrong once is what partly prompted me to ask this question.

推荐答案

如果将 1.0 以下的最大值乘以 someInt (> 0),结果永远不会是 someInt.

If you multiply the greatest value below 1.0 with someInt (> 0), the result will never be someInt.

这可以针对这样的整数进行详尽的测试:

This can be exhaustively tested for integers like this:

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

该代码段不产生任何输出.

The snippet produces no output.

(Math.ulp 返回给定双精度值和下一个更大的双精度值之间的距离.因此断言确保 greatestLessThanOne 确实是小于 1.0 的最大值.)

(Math.ulp returns the distance between the given double and the double value next larger in magnitude. The assertion thus ensures that greatestLessThanOne is indeed the greatest value less than 1.0.)

换句话说,你的线路

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

永远不会产生 ArrayIndexOutOfBoundsException.

will never give rise to an ArrayIndexOutOfBoundsException.

此外,根据 Mark Dickinsons 对此处的评论,这在与双精度相乘时也成立.

Furthermore, according to Mark Dickinsons comment over here, this holds also when multiplying with a double.

在舍入到最近模式下使用 IEEE 754 浮点运算,您可以证明 x * y < y 对于任何 x <;1.0 和任何非微小的正 y.(如果 y 是次正规数或最小的正正规数,它可能会失败.)

With IEEE 754 floating-point arithmetic in round-to-nearest mode, you can show that x * y < y for any x < 1.0 and any non-tiny positive y. (It can fail if y is either subnormal or the smallest positive normal number.)

这篇关于0.99999999999 相乘时可以四舍五入为 1.0 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆