“浮点”与“双精度”精度

问题描述 投票:0回答:5

代码

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 floating-point
5个回答
160
投票

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

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

由于这种编码,许多数字都会有小的变化以允许它们被存储。

此外,有效位数可能会略有变化,因为它是二进制表示形式,而不是十进制表示形式。

单精度(浮点)为您提供 23 位有效数、8 位指数和 1 位符号位。

双精度 (double) 为您提供 52 位有效数、11 位指数和 1 位符号位。


45
投票

双打总是有 16 个有效值吗 数字,而浮点数总是 7 重要数字?

不。双精度数始终具有 53 个有效位,浮点数始终具有 24 个有效位(非正规数、无穷大和 NaN 值除外,但这些是不同问题的主题)。这些是二进制格式,您只能用二进制数字(位)来清楚地说明它们表示的精度。 这类似于二进制整数可以存储多少位的问题:无符号 32 位整数可以存储最多 32 位的整数,这不能精确映射到任意数量的十进制数字:最多的所有整数可以存储最多 9 位小数,但也可以存储很多 10 位数字。

为什么不加倍 有14位有效数字吗?

double 的编码使用 64 位(1 位用于符号,11 位用于指数,52 个显式有效位和 1 个隐式位),这是
double

用于表示浮点型的位数(32 位) .


11
投票
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

)


3
投票
IEEE 754

的工作原理,并且二进制不能很好地转换为十进制,所以它不完全是 double 精度。如果您有兴趣,请看一下标准。


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.