8
myInt = int( 5 * myRandom() )

myRandom()是一个随机生成的浮点数,应该是 0.2。

所以这个语句应该评估为 1

我的问题:是否有可能由于浮点错误它不会评估为 1

例如,如果由于浮点错误,应该是0.2的东西会比这更少吗?例如,IE 考虑以下 3 种可能性:

int(5 * 0.2 )                = 1 //case 1 normal
int(5 * 0.2000000000000001 ) = 1 //case 2 slightly larger, its OK
int(5 * 0.1999999999999999 ) = 0 //case 3 negative, is NOT OK, as int() floors it

case3甚至可能吗?0.1999999999999999浮点错误的结果吗?到目前为止,我实际上从未见过负的 epsilon,只有情况 2,当它稍微大一点时,这没关系,就像当它被强制转换为 int() 时,它会“降低”它的正确结果。但是,对于负 epsilon,“地板”效应将使生成的 0.9999999999999996 评估为 0。

4

5 回答 5

3

myRandom 不可能返回 .2,因为 .2 不能表示为浮点数或双精度数,假设您的目标系统使用 IEEE 754 二进制浮点标准,这是绝大多数的默认值。

如果 myRandom() 返回最接近 0.2 的可表示数,则 myInt 将为 1,因为可表示为浮点数的最接近 .2 的数略大于 0.2(它是 0.20000000298023223876953125),最接近的可表示双精度也是如此(0.200000000000000011102230246225156509042361)66809042361 .

在其他情况下,这将不是真的。例如,最接近 0.6 的双精度数是 0.59999999999999997779553950749686919152736663818359375,所以 myInt 将是 2,而不是 3。

于 2012-07-05T19:25:51.570 回答
1

是的,这是可能的,至少就 C 标准而言。

该值0.2不能以二进制浮点格式精确表示。因此,返回的值myRandom()将略低于或略高于数学值0.2。C 标准允许任一结果。

现在很可能 IEEE 语义只允许结果略大于0.2- 但 C 标准不需要 IEEE 语义。这是假设结果是从 value 中尽可能精确地得出的0.2。如果该值是由一系列浮点运算生成的,每个运算都会引入一个小错误,那么它很容易小于或大于0.2

于 2012-07-05T19:19:27.410 回答
1

这不是浮点错误,而是浮点的工作方式。任何不是 1/(2 的幂)的分数都无法精确表示,并且将向上或向下舍入到最接近的可表示数字。

您可以通过在转换为整数之前乘以大于 1 的小 epsilon 来修复您的代码。

myInt = int( 5 * myRandom() * 1.000000000000001 )

看看每个计算机科学家应该知道的关于浮点运算的知识

于 2012-07-05T19:23:39.110 回答
0

为什么不将浮点数乘以 5.0,然后使用 round 函数正确舍入呢?

于 2012-07-05T19:58:42.340 回答
0

这是可能的,具体取决于您选择的数字。要检查特定数字,您始终可以以很高的精度打印它们: printf("%1.50f", 0.2)

于 2012-07-05T19:52:31.690 回答