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位符号位.
Ste*_*non 39
双打总是有16个有效数字,而浮点数总是有7个有效数字吗?
不是.双打总是有53个有效位,浮点数总是有24个有效位(除了非正规数,无穷大和NaN值,但这些是不同问题的主题).这些是二进制格式,您只能用二进制数字(位)清楚地说出它们的表示精度.
这类似于可以在二进制整数中存储多少位数的问题:无符号32位整数可以存储最多32位的整数,这不会精确映射到任意数量的十进制数字:所有整数最多为可以存储9个十进制数字,但也可以存储许多10位数字.
为什么双打没有14位重要人物?
double的编码使用64位(符号为1位,指数为11位,显式有效位为52,隐式位为一位),这是用于表示浮点(32位)的位数的两倍.
它通常基于基数2中的指数和有效数的有效数字,而不是基数10.然而,从我在C99标准中可以看出,浮点数和双精度没有指定的精度(除了1和1 + 1E-5
/ 的事实)1 + 1E-7
可以区分[ float
和double
repsectively]).但是,有效数字的数量留给了实现者(以及他们在内部使用的基数,换句话说,实现可以决定基于基数3中的18位精度).[1]
如果需要知道这些值,则常量FLT_RADIX
和FLT_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)