c - float 不准确

标签 c floating-point type-conversion rounding

在以下程序中混合 int 和 double 会产生奇怪的结果:

int main()
{
    double x = 9.90, y = 10.0, z, w;
    int    ip, fp;

    z = y - x;

    ip = (int) z;

    w = (z - ip)*100;

    printf( "\nx = %f\ty = %f\tz = %f\tw = %f\n",
            x, y, z, w );

    printf("\nip = %d", ip); /* So far, so good */

    fp = (int) w; /* Why does fp get 9 and not 10??? */

    printf("\nfp = %d\n", fp);

    return 0;
}

结果:

x = 9.900000    y = 10.000000   z = 0.100000    w = 10.000000

ip = 0
fp = 9 (Should be 10!)

使用 MingGW (WinXP) e Clang (MacOSX) 的结果相同。谁能解释一下这种奇怪的行为吗?

最佳答案

问题在于,您实际上是在尝试执行 w = 0.1 * 100,并且值 0.1 无法用浮点精确表示(与 1 的方式相同)/3 无法精确表示为十进制)。

二进制 0.1 得到的结果是:

0.00011001100110011001100110011001100110011001100110011001...

最后 4 位数字永远重复。

尽管 double 没有无限数量的位,所以它实际上是:

1.100110011001100110011001100110011001100110011001100110 * 2**(-4)

其中数字因不适合而被丢弃,以“01001001...”开头。由于丢弃的数字以 0 开头,因此数字将向下舍入。这意味着您实际上最终会执行类似 w = 0.9999999999 * 100 的操作。

关于c - float 不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15754711/

相关文章:

Javascript:转换代码字符串并返回

c - "invalid type argument of unary ' *' C

c - 如何在eclipse中查看c标准库函数源代码

c - 结构体入口声明了一个数组类型的字段,但编译器说它是一个指针

java - 用Java写一个float数组到文件

c - 如何解释 C 中的浮点文字?

c - 如何设计一个不使用这么多内存的哈希表?

python - 为什么 sys.maxint < (sys.maxint - 100 + 0.01) 在 Python 中?

java - 将非常大的二进制字符串转换为长字符串

java - 我应该使用什么数据类型来存储非终止有理数