'浮动'与'双'精度

foo*_*foo 145 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);
Run Code Online (Sandbox Code Playgroud)

会给你输出

x=3.141593
z=3.141593
x=3.141592741012573242
z=3.141592653589793116
Run Code Online (Sandbox Code Playgroud)

输出的第三行741012573242是垃圾,第四行116是垃圾.双打总是有16个有效数字,而浮点数总是有7个有效数字吗?为什么双打没有14位重要人物?

Ala*_*nse 137

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

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

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

此外,有效位数可以稍微改变,因为它是二进制表示,而不是十进制表示.

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

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

  • -1这个陈述是公然错误的:"由于这种编码,你永远不能保证你的价值不会发生变化." (20认同)
  • @Alan:C99不需要IEEE浮点数; 它只是推荐它. (15认同)
  • @Alan:在IEEE 754下,很容易保证值"0.5","0.046875"或"0.376739501953125"与其十进制表示相比没有变化.(这些是在尾数中具有分子拟合的二元有理数和在指数中拟合分母的基数2对数.) (12认同)
  • C99确实如此,以前由编译器决定. (4认同)
  • @Alan:R ..是对的; 附件F(规定了IEEE-754绑定)是规范性的,但只有在实现定义了`__STDC_IEC_559__`时才有效.没有定义该宏的实现可以自由地不符合IEEE-754. (4认同)
  • `double`s的53位给出大约16位精度.`float`的24位给出大约7位数的精度. (4认同)

Ste*_*non 39

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

不是.双打总是有53个有效,浮点数总是有24个有效(除了非正规数,无穷大和NaN值,但这些是不同问题的主题).这些是二进制格式,您只能用二进制数字(位)清楚地说出它们的表示精度.

这类似于可以在二进制整数中存储多少位数的问题:无符号32位整数可以存储最多32位的整数,这不会精确映射到任意数量的十进制数字:所有整数最多为可以存储9个十进制数字,但也可以存储许多10位数字.

为什么双打没有14位重要人物?

double的编码使用64位(符号为1位,指数为11位,显式有效位为52,隐式位为一位),这是用于表示浮点(32位)的位数的两倍.


abe*_*312 11

float:23位有效数字,8位指数和1位符号位.

double:52位有效数字,11位指数和1位符号位.


use*_*379 9

它通常基于基数2中的指数和有效数的有效数字,而不是基数10.然而,从我在C99标准中可以看出,浮点数和双精度没有指定的精度(除了1和1 + 1E-5/ 的事实)1 + 1E-7可以区分[ floatdoublerepsectively]).但是,有效数字的数量留给了实现者(以及他们在内部使用的基数,换句话说,实现可以决定基于基数3中的18位精度).[1]

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

它被称为a的原因double是因为用于存储它的字节数是浮点数的两倍(但这包括指数和有效数).IEEE 754标准(大多数编译器使用)为有效数分配相对更多的位而不是指数(23到9 float对比52到12 double),这就是为什么精度超过两倍.

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


Chr*_*ash 9

float有23位精度,double有52位.