C 浮点类型的有效位数

C 浮点类型的有效位数,c,floating-point,floating-point-conversion,C,Floating Point,Floating Point Conversion,C中对类型float的描述提到有效位数为6。但是, float f = 12345.6; 然后使用printf()打印它不会打印12345.6,而是打印12345.599609。那么,对于浮点类型,“6位有效数字”(如果是双精度的,则为“15”)意味着什么呢?6位有效数字意味着最大误差约为+/-0.0001%。单浮点值实际上有大约7.2位精度()。这意味着误差约为+/-12345.6/10^7=0.00123456。这是您的错误顺序(0.000391)。这里的问题是您无法保证数字可以存储在浮点

C中对类型
float
的描述提到有效位数为
6
。但是,

float f = 12345.6;

然后使用printf()打印它不会打印
12345.6
,而是打印
12345.599609
。那么,对于浮点类型,“6位有效数字”(如果是双精度的,则为“15”)意味着什么呢?

6位有效数字意味着最大误差约为+/-0.0001%。单浮点值实际上有大约7.2位精度()。这意味着误差约为+/-12345.6/10^7=0.00123456。这是您的错误顺序(0.000391)。

这里的问题是您无法保证数字可以存储在浮点数中。你需要用尾数、基数和指数来表示这个数字。数字
printf(…)
显示的是存储的真实浮点数。您无法保证浮点数中的有效位数。

根据,并非所有十进制数都能准确存储在内存中。根据表示的大小,错误可能达到某个最大值。对于
float
这是
0.0001%
(6个有效数字=
10^-6
=
10^-4%


在您的例子中,错误是
(12345.6-12345.599609)/12345.6=3.16e-08
远低于浮点的最大错误。

您看到的并不是有效数字的任何问题,而是计算机上的数字是以二进制存储的,并且3/5(=0.6)没有有限二进制表示。二进制中的3/5看起来像0.10011001…,“1001”模式永远重复。此序列相当于0.599999。。。重复。实际上,在出现任何与精度相关的错误之前,小数点右边的小数点后三位


这与没有1/3的有限基数-10表示法相似;0.3333永远重复。

请注意,浮点类型不是以10为基数存储的,因此有效小数位数必须是近似值。实际上exp有8位,frac有23位。