'浮动'与'双'精度

时间:2011-02-23 23:21:09

标签: c floating-point

代码

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位重要人物?

6 个答案:

答案 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可以区分[floatdouble具有代表性]。但是,有效数字的数量留给了实现者(以及他们在内部使用的基数,换句话说,实现可以决定基于基数3中的18位精度)。 [1]

如果您需要知道这些值,则常量FLT_RADIXFLT_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 精度。如果您有兴趣,请查看标准。