C乘法误差

时间:2014-03-27 02:13:00

标签: c math floating-point

为什么我运行C代码

float x = 4.2
int y = 0
y = x*100
printf("%i\n", y);

我回来了419?不应该是420吗? 这让我很难过。

4 个答案:

答案 0 :(得分:3)

为了说明,请查看中间值:

int main()
{
    float x = 4.2;
    int y;

    printf("x = %f\n", x);
    printf("x * 100 = %f\n", x * 100);
    y = x * 100;

    printf("y = %i\n", y);

    return 0;
}

x = 4.200000            // Original x
x * 100 = 419.999981    // Floating point multiplication precision
y = 419                 // Assign to int truncates

Per @ Lutzi的优秀建议,如果我们打印所有浮动值的精度高于它们所代表的值,则会更清楚地说明这一点:

...
printf("x = %.20f\n", x);
printf("x * 100 = %.20f\n", x * 100);
...

然后您可以看到分配给x的值并不完全准确:

x = 4.19999980926513671875
x * 100 = 419.99998092651367187500
y = 419

答案 1 :(得分:1)

浮点数存储为近似值 - 而不是精确的浮点值。它有一个表示,当您将结果转换为整数时,结果会被截断。您可以查看有关代表here的更多信息。

这是单精度浮点数的示例表示:

enter image description here

答案 2 :(得分:0)

4.2不在浮点数的有限数字空间内,因此系统使用最接近的可能近似值,略低于4.2。如果你现在将它乘以100(这是一个精确的浮点数),你得到419.99somethingprintf() %i {{1}}执行此操作不会进行舍入,而是截断 - 所以得到419。

答案 3 :(得分:0)

浮点数不足以精确存储4.2。如果你以足够的精度打印x,你可能会看到它出现在4.19999995左右。乘以100得到419.999995并且整数赋值截断(向下舍入)。如果你将x设为double,它应该可以工作。