C 为什么产出会有差异?

C 为什么产出会有差异?,c,floating-point,C,Floating Point,使用下面给出的C代码(在Visual Studio中编写): 生成输出: 0.666667 但是,当%5.6f更改为%5.20f时,输出更改为: 0.666668653488159000 我的问题是,为什么类似的十进制数的输出会发生细微的变化?这是因为在浮点中可能没有0.66666666…66667的精确表示。这是因为在浮点中可能没有0.6666666666…6666667的精确表示。与整数不同,它可以精确地表示在任何基数中,相对较少的十进制分数有一个精确的表示在基数-2小数格式中 这意味着FP

使用下面给出的C代码(在Visual Studio中编写):

生成输出: 0.666667

但是,当%5.6f更改为%5.20f时,输出更改为: 0.666668653488159000


我的问题是,为什么类似的十进制数的输出会发生细微的变化?

这是因为在浮点中可能没有0.66666666…66667的精确表示。

这是因为在浮点中可能没有0.6666666666…6666667的精确表示。

与整数不同,它可以精确地表示在任何基数中,相对较少的十进制分数有一个精确的表示在基数-2小数格式中

这意味着FP整数是精确的,通常FP分数不是


因此,对于两个数字,例如0.01到0.99,只有0.25、0.50和0.75(和0)具有精确的表示。通常情况下,随着输出的四舍五入,这并不重要,事实上,对于格式中可用的精度来说,已知的物理常数很少。

与整数不同,整数可以精确地以任何基数表示,相对较少的小数部分可以精确地以基数-2小数格式表示

这意味着FP整数是精确的,通常FP分数不是


因此,对于两个数字,例如0.01到0.99,只有0.25、0.50和0.75(和0)具有精确的表示。通常情况下,随着输出的四舍五入,这并不重要,实际上,对于格式中可用的精度来说,已知的物理常数很少。

精度以指数格式存储,例如(-/+)ax10^n。如果数据类型为32位,则1位用于符号,8位用于a,其余为n。所以,它不存储点后20位的值。因此,在此编译器中,您将永远无法获得正确的值。

精度以指数格式存储,例如(-/+)ax10^n。如果数据类型为32位,则1位用于符号,8位用于a,其余为n。所以,它不存储点后20位的值。因此,在这个编译器中,您永远不会得到正确的值。

浮点类型只有23位表示小数部分,20太多。

浮点类型只有23位表示小数部分,20太多。

当您使用32位浮点时,计算机表示
2./3的结果。
as 11184811/16777216,正好是0.6666686534881591796875。在您使用的浮点中,数字总是表示为某个整数乘以某个二的幂(可能是负的二的幂)。由于限制了整数的大小(当您使用
float
时,整数必须适合24位,不包括符号),最接近2/3的表示值为11184811/16777216

带有“%5.6f”的
printf
显示“0.66666 7”的原因是“%5.6f”只要求六位数字,因此数字在第六位四舍五入

使用
%5.20f
printf
显示“0.6666666 8653488159000”的原因是您的
printf
实现在17位之后“放弃”,这在某种意义上已经足够接近了。人们可能会认为,
printf
的一些实现更好地打印所表示的值,使其尽可能接近所请求的格式。在本例中,它们将显示“0.6666666 8653488159180”,如果您要求更多数字,它们将显示精确值“0.6666666 86534881591796875”


(浮点格式通常表示为符号,介于1[包括]和2[排除]之间的分数),一个指数,而不是一个符号、一个整数和一个指数。从数学上讲,它们在指数中的调整是相同的:每个数字都可以用一个符号、一个24位无符号整数和一个指数表示,它等于一个带符号的数、一个介于1和2之间的分数以及一个调整后的指数。使用整数版本往往会使证明更容易,有时有助于解释。)

当使用32位浮点时,计算机将
2./3的结果表示为11184811/16777216,正好是0.666666686534881591796875。在您使用的浮点中,数字总是表示为某个整数乘以某个二的幂(可能是负的二的幂)。由于限制了整数的大小(当您使用
float
时,整数必须适合24位,不包括符号),最接近2/3的表示值为11184811/16777216

带有“%5.6f”的
printf
显示“0.66666 7”的原因是“%5.6f”只要求六位数字,因此数字在第六位四舍五入

使用
%5.20f
printf
显示“0.6666666 8653488159000”的原因是您的
printf
实现在17位之后“放弃”,这在某种意义上已经足够接近了。人们可能会认为,
printf
的一些实现更好地打印所表示的值,使其尽可能接近所请求的格式。在本例中,它们将显示“0.6666666 8653488159180”,如果您要求更多数字,它们将显示精确值“0.6666666 86534881591796875”


(浮点格式通常表示为符号,介于1[包括]和2[排除]之间的分数),一个指数,而不是一个符号、一个整数和一个指数。从数学上讲,它们在指数中的调整是相同的:每个数字都可以用一个符号、一个24位无符号整数和一个指数表示,它等于一个带符号的数、一个介于1和2之间的分数以及一个调整后的指数。使用整数版本往往会使校对更容易,有时有助于解释。)

拿铅笔和纸。将两个数字中较长的四舍五入,小数点后只能有6位数字。明白了吗?0.666668653488159000到小数点后6位是“0.66666 7”,这就是
%5.6
是一个
#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
    float i = 2.0/3.0;
    printf("%5.6f", i);
    return 0;
}