浮点数与双精度


155

代码

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位有效数字?

Answers:


146

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

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

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

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

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

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


4
C99做到了,以前取决于编译器。
艾伦·盖林斯

21
-1该语句是公然错误的:“由于这种编码,您永远不能保证您的值不会改变。”
R .. GitHub停止帮助ICE,

16
@Alan:C99不需要IEEE浮点;它只是推荐它。
R .. GitHub停止帮助ICE,

4
@Alan:R ..是正确的;附件F(指定IEEE-754绑定)是规范性的,但仅在实现定义时有效__STDC_IEC_559__。没有定义该宏的实现是自由的,不符合IEEE-754。
斯蒂芬·佳能

12
@Alan:在IEEE 754,它很容易保证存在的值没有变化0.50.0468750.376739501953125对他们的十进制表示。(这些都是直截了当的有理数,在尾数中有分子拟合,在指数中有分母以2为底的对数。)
R .. GitHub停止帮助ICE

42

双打是否总是有16个有效数字,浮子总是有7个有效数字?

不能。双精度数总是有53个有效位,而浮点数总是有24个有效(不规范,无穷大和NaN值除外,但这是另一个问题的主题)。这些是二进制格式,您只能用二进制数字(位)清楚地说明其表示的精度。

这类似于一个二进制整数中可以存储多少个数字的问题:一个无符号的32位整数可以存储最多32位的整数,它不能精确地映射到任意数量的十进制数字:最大为可以存储9个十进制数字,但也可以存储很多10个数字。

为什么双打没有14位有效数字?

double的编码使用64位(1位为正负号,11位为指数,52位显式有效位和1个隐含位),是表示浮点数的位数(32位)的两倍


15

浮点数:有效位23位,指数8位和1个符号位。

double:有效位52位,指数11位和1个符号位。


11

它通常基于以2为底的指数和有效位数的有效数字,而不是以10为底的数字。但是,根据我在C99标准中所说的,浮点数和双精度数没有指定的精度(除了1和1 + 1E-5/ 1 + 1E-7是可区分的(float并分别double代表))。但是,有效数字的数量留给了实现者(以及它们在内部使用的基数,因此,实现可以基于基数3中的18位精度来决定使用有效数字)。[1]

如果您需要了解这些值,则在float.h中定义常量FLT_RADIXFLT_MANT_DIG(和DBL_MANT_DIG/ LDBL_MANT_DIG)。

之所以称为a,double是因为用于存储它的字节数是float数的两倍(但这包括指数和有效位数)。IEEE 754标准(大多数编译器使用)为有效位数分配的位数要比指数分配的位数相对较多(对于,分配23位至9位,对于分配float52位至12位double),这就是为什么精度提高了一倍以上的原因。

1:第5.2.4.2.2节(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf


错别字?C89要求最多的ε 1E-9double,不是1E-7
Rufflewind '16


4

由于IEEE 754的工作原理,并且二进制不能真正转换为十进制,因此它并不是精度。如果您有兴趣,请看一下标准。


4

float代表浮点数。在C中,如果总位数的精度为7,则使用float数据类型。例如:-十进制数。12.3546987不能存储在float中,因为它总共有9位数字。输出将显示为12.354699,即前7位将显示为输入中的输入,而第8位将四舍五入.float类型可以表示值从大约1.5 x 10 ^(-45)到3.4 x 10 ^(38)的范围。就内存分配而言,float是单精度的32位浮点数据类型。

与float不同,double的精度为15到16位。double的范围是5.0×10 ^(− 345)到1.7×10 ^(308)。就字节分配而言,double是64位浮点数据类型。

使用时会出现问题。浮点数或double数不会影响printf,但在scanf的情况下,将根据总编号使用适当的数据类型。浮号的位数 从输入中读取。

因此,为获得更高的数据精度,双精度优于浮点精度。

希望这可以帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.