转换为int和浮点错误?

时间:2012-07-05 19:13:00

标签: c casting floating-point integer

myInt = int( 5 * myRandom() )

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

所以这句话应该评估为1

我的问题:是否可能由于浮点错误而无法评估为1

例如,如果由于浮点错误,应该 0.2 的东西可能 LESS ? 例如,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.

5 个答案:

答案 0 :(得分:3)

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

如果myRandom()返回最接近.2的可表示数字,则myInt将为1,因为最接近.2的数字表示为浮点数略大于.2(它是0.20000000298023223876953125),因此是最接近的可表示的双数(0.20000000000000001110223024625156540423631668090820312)。

在其他情况下,这不是真的。例如,最接近.6的双倍是0.59999999999999997779553950749686919152736663818359375,所以myInt将是2,而不是3。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

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

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

请参阅What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 3 :(得分:0)

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

答案 4 :(得分:0)

为什么不将你的浮点数乘以5.0,然后使用圆函数来正确地舍入它?