浮点与双精度

下面的代码

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是可区分的[ floatdouble ])。 然而,有效数字的数量留给实施者(以及他们在内部使用哪个基地,换句话说,一个实施可以决定以基数3的18位精度为基础)。 [1]

如果您需要知道这些值,则在float.h中定义常量DBL_MANT_DIGFLT_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的工作原理,并不是精度的,而且二进制不能很好地转化为十进制。 如果你有兴趣,请看标准。