代码
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 编码。
这种类型的编码使用符号、尾数和指数。
由于这种编码,许多数字都会有小的变化以允许它们被存储。
此外,有效位数可能会略有变化,因为它是二进制表示形式,而不是十进制表示形式。
单精度(浮点)为您提供 23 位有效数、8 位指数和 1 位符号位。
双精度 (double) 为您提供 52 位有效数、11 位指数和 1 位符号位。
双打总是有 16 个有效值吗 数字,而浮点数总是 7 重要数字?
不。双精度数始终具有 53 个有效位,浮点数始终具有 24 个有效位(非正规数、无穷大和 NaN 值除外,但这些是不同问题的主题)。这些是二进制格式,您只能用二进制数字(位)来清楚地说明它们表示的精度。 这类似于二进制整数可以存储多少位的问题:无符号 32 位整数可以存储最多 32 位的整数,这不能精确映射到任意数量的十进制数字:最多的所有整数可以存储最多 9 位小数,但也可以存储很多 10 位数字。
为什么不加倍 有14位有效数字吗?
doubledouble 的编码使用 64 位(1 位用于符号,11 位用于指数,52 个显式有效位和 1 个隐式位),这是
用于表示浮点型的位数(32 位) .
1 + 1E-5
/
1 + 1E-7
是可区分的[分别为 float
和 double
])。然而,有效数字的数量留给实现者(以及他们内部使用的基数,因此换句话说,实现可以决定基于基数 3 中的 18 位精度)。 [1]如果您需要知道这些值,常量
FLT_RADIX
和
FLT_MANT_DIG
(以及 DBL_MANT_DIG
/ LDBL_MANT_DIG
)在 float.h 中定义。它被称为
double
的原因是因为用于存储它的字节数是浮点数的两倍(但这包括指数和有效数)。 IEEE 754 标准(大多数编译器使用)为尾数分配的位比指数相对更多(
float
为 23 到 9,double
为 52 到 12),这就是精度增加一倍以上的原因。1:第 5.2.4.2.2 节 ( http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf