浮点与双精度
下面的代码
float x = 3.141592653589793238; double z = 3.141592653589793238; printf("x=%f\n", x); printf("z=%f\n", z); printf("x=%20.18f\n", x); printf("z=%20.18f\n", z);
会给你输出
x=3.141593 z=3.141593 x=3.141592741012573242 z=3.141592653589793116
输出741012573242
的第三行是垃圾,第四行116
是垃圾。 双打总是有16位有效数字,而花车总是有7位有效数字? 为什么不打双打有14位有意义的数字?
C中的浮点数使用IEEE 754编码。
这种types的编码使用符号,有效数和指数。
由于这种编码,许多数字将有小的变化,让他们被存储。
此外,有效数字的数目可以稍微改变,因为它是一个二进制表示,而不是一个小数。
单精度(浮点)给你23位有效位,8位指数和1位符号位。
双精度(双精度)给出52位有效位,11位指数和1位符号位。
双打总是有16位有效数字,而花车总是有7位有效数字?
双数总是有53个有效位 ,浮点数总是有24个有效位 (非规范化,无穷大和NaN值除外,但这些是另一个问题的主题)。 这些是二进制格式,只能用二进制数字(比特)清楚地说明其表示的精确度。
这类似于在一个二进制整数中可以存储多less个数字的问题:无符号的32位整数可以存储具有多达32位的整数,其不精确映射到任何十进制数字:所有整数可以存储9位十进制数字,但也可以存储大量的10位数字。
为什么不打双打有14位有意义的数字?
双精度的编码使用64位(1位为符号,11位为指数,52位显式有效位和一位隐式位),这是用于表示浮点数(32位)的位数的两倍 。
它通常是基于指数和有效数字的基数2,而不是基数10的有效数字。但是从C99标准中我可以看出,浮点数和双精度都没有指定的精度(除了1和1 + 1E-5
/ 1 + 1E-7
是可区分的[ float
和double
])。 然而,有效数字的数量留给实施者(以及他们在内部使用哪个基地,换句话说,一个实施可以决定以基数3的18位精度为基础)。 [1]
如果您需要知道这些值,则在float.h中定义常量DBL_MANT_DIG
和FLT_MANT_DIG
(和DBL_MANT_DIG
/ LDBL_MANT_DIG
)。
它被称为double
的原因是因为用来存储它的字节数是浮点数的两倍(但是这包括指数和有效数)。 大多数编译器使用的IEEE 754标准为有效位分配的位数比指数要多( float
为23到9, double
精度为52到12),这就是为什么精度增加了一倍多的原因。
1:第5.2.4.2.2节( JTC1/SC22/WG14/www/docs/n1256.pdf )
一个浮点数有23位精度,而一个浮点数有52位。
float:23位有效位,8位指数和1位符号位。
双精度:52位有效位,11位指数和1位符号位。
由于IEEE 754的工作原理,并不是双精度的,而且二进制不能很好地转化为十进制。 如果你有兴趣,请看标准。