【问题标题】:Greater than lesser than comparison in floating points in C [duplicate]大于小于C中浮点的比较[重复]
【发布时间】:2017-11-23 17:11:21
【问题描述】:

考虑以下代码:

float x = 0.1;
if ( x> 0.1){
    printf("if");
}

现在,当我检查相等性时,说明 x 通过在末尾填充 0 被转换为 double,但 RHS 上的 0.1 存储在 double 中,因此不等式。 但是如果我通过这个逻辑,上面代码中的“if”应该是假的,但它却是真的。 为什么?

【问题讨论】:

  • 浮点数并不完全精确。它们不能代表每个数字,因此会有舍入误差。在这种情况下,它显然向上舍入到一个比0.1 稍大一点的值。
  • @ChristianGibbons -- 请注意常量0.1 也是一个浮点值,不准确地表示为double。
  • @DavidBowling 确实如此。这是我的疏忽错误。
  • float x = 0.1; 已经发生四舍五入(向上)只是一个疏忽。

标签: c


【解决方案1】:

(尽管 C 支持的所有浮点方案都要求 double 集合是 float 集合的超集,但限制对 IEEE754 的回答。)

0.1 是0.1000000000000000055511151231257827021181583404541015625

0.1f 是0.100000001490116119384765625。

0.100000001490116119384765625 被提升为double,但它的数字相同,因为所有floats 都可以精确地表示为doubles。

所以(double)(0.1f) 大于0.1,占结果。

【讨论】:

    【解决方案2】:

    关键问题是0.1 不能准确用二进制表示。将其转换为以 2 为基数,您会得到一个在小数部分带有 repetend 的数字,1001 永远重复(就像十进制一样,1/3 最终以 3 永远重复)。

    当将0.1 存储在浮点数中时,它最终会四舍五入到最后一位*),因此float 0.1 大于double 0.1

    所以,是的,将float 转换为double 只是附加(二进制)零,但首先float 已经有点太大了。


    *) 这实际上取决于您的实现使用的浮点数表示。对于 IEEE 754 floats,表示将以

    结尾
    ... 10011001100
    

    因为下一个数字是1,所以向上舍入,所以最终结果以

    结尾
    ... 10011001101
    

    【讨论】:

    • “小数部分中的句号”让我觉得有一个“。”在分数部分。我认为更清楚地说,小数部分中的二进制数字会永远持续下去,并具有重复的模式。
    • @EricPostpischil 直接翻译德语单词,数学语言不同:(在德语中,它确实是一个“句号”(在统一重复模式的意义上);我只是查了一下,在英语中它被称为“repetend” ...
    • 嗯,我刚学了一个新词。
    猜你喜欢
    • 2020-04-22
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    • 2022-06-23
    • 2018-03-26
    • 1970-01-01
    • 2011-10-24
    相关资源
    最近更新 更多