c - 比较相同的浮点值时出现奇怪的输出?

标签 c floating-point precision

Comparing Same Float Values In C

strange output in comparison of float with float literal

Float addition promoted to double?


我阅读了上面关于 float 的链接,但甚至得到了奇怪的输出。

#include<stdio.h>
int main()
{
    float x = 0.5;

    if (x == 0.5)
        printf("IF");

    else if (x == 0.5f)
        printf("ELSE IF");

    else
        printf("ELSE");
}

现在,根据促销规则,“ELSE IF”不是必须打印吗?

但是,这里打印的是“IF


编辑: 是因为 0.5 = 0.1 在二进制中,之后一切都是 0 并且精度损失因此没有影响,所以比较 IF 返回 true。

如果它是 0.1, 0.2, 0.3, 0.4, 0.6, 0.7.... ,那么 Else If block 返回 true。


请原谅我问同样的问题,因为我从上面的链接中读到绝对不能进行 float 比较。

但是,这种意外行为的原因是什么?

最佳答案

Floating point numbers are never accurate.

这个说法是错误的。有些 float 是准确的,比如1.0、12345.0、12345.5、-2.25。所有这些数字都可以表示为除以 2 的幂的整数。所有不能表示的数字也不准确。

在您的特定情况下,float x = 0.5 导致 x 的值为 1.00000000 * 2^-1。当您将它与 double 0.5 进行比较时,两个操作数都转换为 double,因此比较变为 1.000000000000000 * 2^-1 == 1.000000000000000 * 2^-1 ,成功。

对于float x = 0.1,它看起来不一样。该值存储为 1.01010101 * 2^-3(或类似格式)。请注意,这已经不准确了。当您将它与 double 0.1 进行比较时, float 在末尾用零扩展,比较结果变为 1.010101010000000 * 2^-3 == 1.010101010101010 * 2^-3,失败了。

关于c - 比较相同的浮点值时出现奇怪的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41691261/

相关文章:

c - LD_PRELOAD什么时候会被忽略

c - 为什么 printf 在调用后不会刷新,除非格式字符串中有换行符?

c - 减去一个子串

c - x86-64 上的 long double 是什么?

iphone - map 套件中的 GPS 精度不如 Maps.app 中那么精确

go - 是否有任何标准库可以将 float64 转换为具有固定宽度和最大有效位数的字符串?

c - 为什么 static char* 需要常量初始化,而 static char** 不需要

c++ - 我应该使用 double 还是 float ?

python - 将 float 转换为等效的四舍五入十进制数

precision - Ada 定点类型的限制