0.1浮点数大于0.1双.我以为它是假的

Hes*_*aqi 100 c c++ floating-point double rounding

让:

double d = 0.1;
float f = 0.1;
Run Code Online (Sandbox Code Playgroud)

应该表达

(f > d)
Run Code Online (Sandbox Code Playgroud)

回来true还是false

根据经验,答案是true.但是,我期待它false.

0.1不能在二进制完美表示,而双具有1516十进制精度位数,并且浮体具有只7.所以,他们两个都不到0.1,而双人更接近0.1.

我需要一个确切的解释true.

ken*_*ytm 172

我想说转换时,答案取决于舍入模式doublefloat.float有24个二进制位的精度,并double有53.在二进制,0.1是:

0.1?? = 0.0001100110011001100110011001100110011001100110011…?
             ^        ^         ^   ^ 
             1       10        20  24
Run Code Online (Sandbox Code Playgroud)

因此,如果我们圆在第24位,我们会得到

0.1?? ~ 0.000110011001100110011001101
Run Code Online (Sandbox Code Playgroud)

它大于精确值,53位数的精确近似值.

  • 准确答案......! (15认同)
  • @HeshamERAQI这两个答案都是正确的 - 我想这个更容易看到*为什么*这种情况发生了.但是,对于这两种解释,考虑如何在截止点处舍入结果至关重要.像其他评论所说的那样,IEEE754,FP表示的事实标准,就是这样做的,但理论上可能会有FP实现只是截断而不是舍入. (2认同)

Sve*_*ach 55

数字0.1将四舍五入到具有给定精度的最接近的浮点表示.这种近似可能大于或小于0.1,因此如果不查看实际值,则无法预测单精度或双精度近似是否更大.

这是双精度值四舍五入到的(使用Python解释器):

>>> "%.55f" % 0.1
'0.1000000000000000055511151231257827021181583404541015625'
Run Code Online (Sandbox Code Playgroud)

这是单精度值:

>>> "%.55f" % numpy.float32("0.1")
'0.1000000014901161193847656250000000000000000000000000000'
Run Code Online (Sandbox Code Playgroud)

所以你可以看到单精度近似更大.

  • 但这取决于实施.我怀疑你的结果是IEEE`double`和`float`,因为这是目前最常用的,但你可能在IBM或Unisys大型机上得到不同的结果. (4认同)
  • @JamesKanze:这是在x86机器上.Python使用本机浮点运算,x86实现(或多或少)符合IEEE-754. (3认同)

sta*_*ast 19

如果您转换.1为二进制,您会得到:

0.000110011001100110011001100110011001100110011001100...

永远重复

映射到数据类型,您得到:

float(.1)  = %.00011001100110011001101
                                     ^--- note rounding
double(.1) = %.0001100110011001100110011001100110011001100110011010

将其转换为基数10:

float(.1)  = .10000002384185791015625
double(.1) = .100000000000000088817841970012523233890533447265625

这取自布鲁斯道森撰写的一篇文章.它可以在这里找到:
双打不是浮点数,所以不要比较它们


xan*_*xan 5

由于无法精确表示,因此比较以 2 为底的 1/10 就像比较以 10 为底的 1/7。

1/7 = 0.142857142857...但是在不同的基数 10 精度(3 位和 6 位小数)进行比较,我们有 0.143 > 0.142857。


Kip*_*Kip 5

我认为Eric Lippert对这个问题的评论实际上是最明确的解释,所以我会将其作为答案重新发布:

假设您计算1/3的3位十进制和6位十进制数.0.111 <0.111111,对吗?

现在假设您正在计算6/9.0.667> 0.666667,对吗?

您不能认为三位十进制中的6/9是0.666因为这不是最接近的3位小数到6/9!