‘ float’与‘ double’精度

密码

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个重要数字?

509239 次浏览

它通常基于基数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,是因为用于存储它的字节数是 float 的两倍(但这同时包括指数和有效数)。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)

C 语言中的浮点数使用 IEEE 754编码。

这种类型的编码使用符号、有效数和指数。

由于这种编码,许多数字将有小的更改,以允许它们被存储。

此外,由于有效数字是二进制,而非十进制,因此数目可能会有轻微的变化。

单精度(float)给出23位有效位、8位指数和1位符号。

Double 精度(Double)给出52位有效位、11位指数和1位符号。

浮点数的精度为23位,而浮点数的精度为52位。

因为 IEEE 754的工作方式,并且因为二进制不能很好地转换为十进制,所以它不完全是 双倍精度。如果你感兴趣,可以看看标准。

双打总是有16个显著 数字,而花车总是有7 重要的数字?

没有。双精度浮点数总是有53个有效 比特,浮点数总是有24个有效 比特(除了异常值、无穷值和 NaN 值,但这些是另一个问题的主题)。这些都是二进制格式,您只能用二进制数字(位)来清楚地说明它们表示的精度。

这类似于一个二进制整数可以存储多少位数字的问题: 一个无符号的32位整数可以存储多达32位的整数,这并不能精确地映射到任何数量的十进制数字: 所有最多可以存储9位十进制数字的整数都可以存储,但是也可以存储大量的10位数字。

为什么不双倍 有14个重要人物?

双精度编码使用64位(符号为1位,指数为11位,显式有效位为52位,隐式有效位为1位) ,即 双倍,用于表示浮点数的位数(32位)。

  • float: 有效位23位,指数8位,符号1位。
  • double:52位有效位,11位指数位和1位符号位。