为什么这个C程序输出“错误”?
#include<stdio.h>
void main()
{
float f = 12345.054321;
printf("%f", f);
getch();
}
输出:
12345.054688
但输出应为12345.054321
。
我在VS2008中使用VC ++。
答案 0 :(得分:10)
它给出了“错误的”答案,因为并非所有真实值都可以通过浮点数表示(或双重表示)。你会得到的是基于底层编码的近似值。
为了表示每个实际值,即使在1.0x10 -100 和1.1x10 -100 (真正的微小范围)之间,您仍然需要无限数量的位。
单精度IEEE754值只有32位可用(其中一些是其他任务,如指数和NaN / Inf表示),因此无法为您提供无限精度。它们实际上有23位可用,精度约为2 24 (有一个额外的隐含位)或仅超过7位小数(log 10 (2 24 )大致是7.2)。
我在引号中加上“错误”这个词,因为它实际上 错误。你对计算机如何代表数字的理解是错的(不要被冒犯,你并不孤单于这种误解)。
转到http://www.h-schmidt.net/FloatApplet/IEEE754.html并在“十进制表示”框中输入您的号码,以查看此操作。
如果你想要一个更准确的数字,使用双精度而不是浮点数 - 它们可以用来表示值的两倍(假设你的C实现分别使用了IEEE754单精度和双精度数据类型的float和double)。 / p>
如果你想要任意精度,你需要使用像GMP这样的“bignum”库,虽然这比本机类型要慢一些,所以请确保你理解权衡。
答案 1 :(得分:2)
十进制数12345.054321无法准确表示为您平台上的float
。您看到的结果是最接近的数字的十进制近似值,可以表示为float
。
答案 2 :(得分:2)
float
是关于方便和速度的,并使用二进制表示 - 如果你关心精度使用十进制类型。
要理解这个问题,请阅读每个计算机科学家应该知道的关于浮点运算的内容: http://docs.sun.com/source/806-3568/ncg_goldberg.html
有关解决方案,请参阅十进制算术常见问题: http://speleotrove.com/decimal/decifaq.html
答案 3 :(得分:0)
单精度浮点值只能表示大约八到九个有效(十进制)数字。除此之外,您还会看到量化错误。
答案 4 :(得分:0)
这与精确度有关。您的号码无法准确存储在浮点数中。