当简单地指定仅包含4个有效数字的浮点值时,我看到了一些错误。我写了一个简短的程序来调试,我不明白问题是什么。在我的平台上验证浮点数的限制之后似乎应该没有任何错误。造成这种情况的原因是什么?
#include <stdlib.h>
#include <stdio.h>
#include <limits>
#include <iostream>
int main(){
printf("float size: %lu\n", sizeof(float));
printf("float max: %e\n", std::numeric_limits<float>::max());
printf("float significant figures: %i\n", std::numeric_limits<float>::digits10);
float a = 760.5e6;
printf("%.9f\n", a);
std::cout.precision(9);
std::cout << a << std::endl;
double b = 760.5e6;
printf("%.9f\n", b);
std::cout << b << std::endl;
return 0;
}
输出:
float size: 4
float max: 3.402823e+38
float significant figures: 6
760499968.000000000
760499968
760500000.000000000
760500000
答案 0 :(得分:3)
float
具有24位精度,大致相当于7位十进制数。 double
具有53位精度,大致相当于16位十进制数。
正如评论中所述,760.5e6
无法完全代表float
;但是,它double
完全可以表示。这就是为什么double
的打印结果是准确的,而float
的打印结果不是。
请求打印比您的浮点数可表示的更多十进制数字是合法的。您报告的结果不是错误 - 它们只是十进制打印算法尽力而为的结果。
答案 1 :(得分:1)
float
中存储的数字是760499968.这是IEEE 754 binary32浮点数的预期行为,通常为float
。
IEEE 754浮点数分为三部分:符号位,指数和尾数。由于所有这些值都存储为位,因此得到的数字排序科学计数法的二进制等价物。尾数位比二进制科学符号中的有效数字允许的二进制数字少一个。
就像十进制科学数字一样,如果指数超过有效数字,你将失去整数精度。
这个类比只延伸到目前为止:尾数是对您可能熟悉的十进制科学符号中的系数的修改,并且在标准中存在某些具有特殊含义的位模式。
这种存储机制的最终结果是整数760500000不能由IEEE 754 binary32
用其23位尾数精确表示:它在2^(mantissa_bits + 1)的整数后失去整数级精度,对于23位尾数浮点数是16777217。可以用浮点数表示的最接近76050000的整数是760499968和76050032,由于round-ties-to-even rule而选择前者用于表示,并且以比浮点数更高的精度打印整数。自然会导致明显的不准确。
答案 2 :(得分:0)
一个double,在你的情况下有64位大小,自然比浮点数更精确,在你的情况下是32位。因此,这是预期的结果
规范并未强制任何类型应正确表示所有小于std :: numeric_limits :: max()的数字及其精度。
答案 3 :(得分:0)
您显示的数字仅在第8位和之后关闭。对于float
,保证准确度在6位数内。如果您只打印了6位数字,输出将四舍五入,您将看到您期望的值。
printf("%0.6g\n", a);