可能重复:
strange output in comparison of float with float literal
当我尝试比较两个相同的float
值时,它不会在以下代码中打印“相等的值”:
void main()
{
float a = 0.7;
clrscr();
if (a < 0.7)
printf("value : %f",a);
else if (a == 0.7)
printf("equal values");
else
printf("hello");
getch();
}
提前致谢。
答案 0 :(得分:25)
虽然很多人会告诉你总是将浮点数与epsilon进行比较(这通常是一个好主意,虽然它应该是被比较的值的百分比而不是固定值),但这里实际上并不需要你正在使用常数。
您的具体问题在于:
float a = 0.7;
使用 double 常量0.7
创建单个精度数字(失去一些精度),同时:
if (a == 0.7)
将比较两个 double 精度数字(首先提升a
)。
将0.7
转换为双倍a
时,将a
转换为浮动0.7
时丢失的精度不会重新获得。
如果你将所有0.7f
值更改为a
(强制浮动而不是加倍),或者只是让float
加倍,它会正常工作 - 我很少使用#include <stdio.h>
int main (void){
float f = 0.7; // double converted to float
double d1 = 0.7; // double kept as double
double d2 = f; // float converted back to double
printf ("double: %.30f\n", d1);
printf ("double from float: %.30f\n", d2);
return 0;
}
现在除非我拥有大量数据并且需要节省空间。
您可以通过以下方式查看此操作:
double: 0.6999999|99999999955591079014994
double from float: 0.6999999|88079071044921875000000
\_ different beyond here.
将输出类似(略微修改以显示差异):
{{1}}
答案 1 :(得分:4)
浮点数不是您认为的那样:以下是两个包含更多信息的来源:What Every Computer Scientist Should Know About Floating-Point Arithmetic和The Floating-Point Guide。
简短的回答是,由于表示浮点数的方式,你不能进行基本的比较或算术,并期望它能够工作。
答案 2 :(得分:3)
您正在将单精度近似值0.7与双精度近似值进行比较。要获得预期的输出,您应该使用:
if(a == 0.7f) // check a is exactly 0.7f
请注意,由于表示和舍入错误,可能不太可能从任何操作得到0.7f。通常,您应该检查fabs(a-0.7)
是否足够接近0
。
不要忘记0.7f的确切值不是0.7,而是略低:
0.7f = 0.699999988079071044921875
0.7的双精度表示的精确值是更好的近似值,但仍不完全是0.7:
0.7d = 0.6999999999999999555910790149937383830547332763671875
答案 3 :(得分:2)
a
是float
; 0.7
是double
类型的值。
两者之间的比较需要转换。编译器会将float
值转换为double
值...并且将float转换为double所产生的值与编译器转换文本字符串所产生的值不同(源代码)到双。
但是请不要将浮点值(float
,double
或long double
)与==
进行比较。
您可能希望阅读"What Every Programmer Should Know About Floating-Point Arithmetic"。
答案 4 :(得分:0)
浮点数缺乏绝对精度使得进行简单比较比整数更难。请参阅有关C中浮动广告的this页面。特别是,从中提取的一个代码段展示了此问题的“解决方法”:
bool AlmostEqual2sComplement(float A, float B, int maxUlps)
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
int aInt = *(int*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
aInt = 0x80000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
int bInt = *(int*)&B;
if (bInt < 0)
bInt = 0x80000000 - bInt;
int intDiff = abs(aInt - bInt);
if (intDiff <= maxUlps)
return true;
return false;
}
一个简单而常见的解决方法是为epsilon提供如下代码:
if (fabs(result - expectedResult) < 0.00001)
这基本上检查了值之间的差异是否在阈值内。请参阅链接文章,了解为什么这并不总是最佳的:)
Another article几乎是与人们在SO上询问浮动时相关的事实上的标准。
答案 5 :(得分:0)
不得将浮点数与“==”运算符进行比较。
不是将浮点数与“==”运算符进行比较,而是可以使用如下函数:
//compares if the float f1 is equal with f2 and returns 1 if true and 0 if false
int compare_float(float f1, float f2)
{
float precision = 0.00001;
if (((f1 - precision) < f2) &&
((f1 + precision) > f2))
{
return 1;
}
else
{
return 0;
}
}
答案 6 :(得分:-1)
如果您需要将a
与0.7
进行比较
if( fabs(a-0.7) < 0.00001 )
//your code
这里0.00001可以改为更少(如0.00000001)或更多(如0.0001)&gt;这取决于您需要的精度。