代码
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位重要人物?
答案 0 :(得分:133)
C中的浮点数使用IEEE 754编码。
这种类型的编码使用符号,有效数和指数。
由于这种编码,许多数字都会有很小的变化,以便存储它们。
此外,有效位数可以稍微改变,因为它是二进制表示,而不是十进制表示。
单精度(浮点数)为您提供23位有效数字,8位指数和1位符号位。
双精度(double)为您提供52位有效数,11位指数和1位符号。
答案 1 :(得分:38)
双打总是有16显着 数字,而花车总是有7 重要人物?
没有。双打总是有53个重要的位,浮点数总是有24个重要的位(除了非正规数,无穷大和NaN值,但这些是不同问题的主题)。这些是二进制格式,你只能用二进制数字(位)清楚地说出它们的表示精度。
这类似于可以在二进制整数中存储多少位数的问题:无符号32位整数可以存储最多32位的整数,这不会精确映射到任意数量的十进制数字:所有整数最多可存储9个十进制数字,但也可存储许多10位数字。
为什么不加倍 有14位重要人物?
double的编码使用64位(符号为1位,指数为11位,显式有效位为52位,隐含位为52位),这是 double 用于表示一个浮点数(32位)。
答案 2 :(得分:10)
float:23位有效数字,8位指数和1位符号。
double:52位有效数字,11位指数和1位符号。
答案 3 :(得分:9)
它通常基于基数2中的指数和有效数的有效数字,而不是基数10.然而,从我在C99标准中可以看出,浮点数和双精度没有指定的精度(除了事实, 1和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)
答案 4 :(得分:9)
float有23位精度,double有52位。
答案 5 :(得分:3)
由于IEEE 754的工作方式,因为二进制文件并不能很好地转换为十进制,所以它并不完全是 double 精度。如果您有兴趣,请查看标准。