C - 打印浮动 - 在转换为int时精度损失

时间:2014-11-04 22:39:38

标签: c++ c casting output

我试图创建一个能够打印浮动的功能。 现在,我遇到了两个奇怪的行为: 有时,像1.3这样的值出现为1.2999999而不是1.3000000,有时像1.234567这样的值出现为1.2345672而不是1.2345670。

这是源代码:

int     ft_putflt(float f)
{
    int     ret;
    int     intpart;
    int     i;

    ret = 0;
    i = 0;
    intpart = (int)f;
    ft_putnbr(intpart);
    ret = ft_nbrlen(intpart) + 8;
    write(1, ".", 1);
    while (i++ < 7)
    {
        f *= 10;
        ft_putchar(48 + ((int)f % 10));
    }
    return (ret);
}

ft_putnbr是好的AFAIK。 ft_putchar是一个简单的调用&#34; write(1,&amp; c,1)&#34;。

test values (value : output)

1.234567  : 1.2345672 (!)

1.2345670 : 1.2345672 (!)

1.0000001 : 1.0000001 OK

0.1234567 : 0.1234567 OK

0.67      : 0.6700000 OK

1.3       : 1.3000000 OK (fixed it)

1.321012  : 1.3210119 (!)

1.3210121 : 1.3210122 (!)

这一切对我来说似乎有点神秘......投射到int时可能会失去精确度吗?

2 个答案:

答案 0 :(得分:1)

是的,当弄乱浮子和整体时,你会失去精确度。

如果两个浮点数具有不同的幅度并且两者都使用完整的精度范围(大约7个十进制数字)然后是,则会在最后的位置看到一些损失,因为浮点数以(符号)的形式存储(尾数) )×2 (指数)。如果两个值具有不同的指数并且您添加它们,则较小的值将减少到尾数中的较少位数(因为它必须适应较大的指数):

PS> [float]([float]0.0000001 + [float]1)
1

对于整数,正常的32位整数能够精确地表示不完全适合浮点数的值。浮动仍然可以存储大约相同的数字,但不再完全相同。当然,这仅适用于足够大的数字,即。即因为一个浮点数有24位精度而且(32位)整数有32位,所以浮点数仍然可以保留幅度和大多数有效位数,但最后的位置可能会有所不同:

PS> [float]2100000050 + [float]100
2100000100

答案 1 :(得分:1)

这是使用有限精度数值表示方案所固有的。给定任何可以表示的数字,A,有一些数字是可以表示的大于A的最小数字,称之为B. A和B之间的数字不能精确表示,必须近似。

例如,让我们考虑使用六位十进制数字,因为这是一个更容易理解的系统作为起点。如果A是.333333,则B是.333334。 A和B之间的数字,例如1/3,不能准确表示。因此,如果你取1/3并将其加到自身两次(或乘以3),你将得到.999999,而不是1.你应该期望在表示的极限看到不精确。