根据this post,在比较float和double时,float应该被视为double。 以下程序似乎没有遵循此声明。这种行为看起来非常不可预测。 这是我的计划:
void main(void)
{
double a = 1.1; // 1.5
float b = 1.1; // 1.5
printf("%X %X\n", a, b);
if ( a == b)
cout << "success " <<endl;
else
cout << "fail" <<endl;
}
我还打印了值的十六进制表示法。它们在两种情况下都不同。我的编译器是Visual Studio 2005
你能解释一下这个输出吗?感谢。
答案 0 :(得分:10)
float f = 1.1;
double d = 1.1;
if (f == d)
在此比较中,f
的值会提升为double
类型。您所看到的问题不是在比较中,而是在初始化中。 1.1
无法完全表示为浮点值,因此f
和d
中存储的值是可以表示的最接近的值。但float
和double
的大小不同,因此具有不同数量的有效位。当f
中的值被提升为double
时,无法获取存储该值时丢失的额外位,因此最终会在额外位中使用全零。那些零位与d
中的位不匹配,因此比较为假。与1.5
进行比较成功的原因是1.5
可以完全表示为float
和double
;它的低位有一堆零,所以当促销添加零时,结果与double
表示相同。
答案 1 :(得分:5)
我找到了对您遇到的问题以及解决方案的正确解释。
请参阅How dangerous is it to compare floating point values?
请注意,请记住,某些值无法在IEEE 754浮点表示中完全表示。使用值1.5的相同示例将按照您的预期进行比较,因为存在1.5的完美表示而没有任何数据丢失。但是,32位和64位的1.1实际上是不同的值,因为IEEE 754标准不能完美地代表1.1。
请参阅http://www.binaryconvert.com
double a = 1.1 --> 0x3FF199999999999A
近似表示= 1.10000000000000008881784197001
float b = 1.1 --> 0x3f8ccccd
近似表示= 1.10000002384185791015625
如您所见,这两个值是不同的。
此外,除非您在某些有限的内存类型环境中工作,否则使用浮点数有点无意义。只需使用双打并避免头痛。
如果您不清楚为什么某些值无法准确表示,请参阅有关如何将小数转换为浮点的教程。
这是一个:http://class.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html
答案 2 :(得分:1)
我认为代码可以在没有类型转换的情况下直接执行float
和double
之间的比较;即使语言规范说float
将被隐式转换,有两种不同的方式可以合理地执行比较,并且两者都没有足够的优势来真正证明“静默”默认行为(即编译的行为)没有产生警告)。如果想要通过将两个操作数评估为double
来执行转换,我建议添加一个显式类型转换以使一个人的意图清楚。在大多数情况下,除了测试以查看特定double
- &gt; float
转换是否可逆而不会丢失精度之外,我怀疑float
值之间的比较可能更合适
从根本上说,在比较任何类型的浮点值X
和Y
时,应将比较视为表示X
或Y
较大,或者数字“无法区分”。应显示X
较大的比较,以表明Y
应表示的数字可能小于X
或接近X
。一个比较说,数字是无法区分的意思正是如此。如果以这种方式查看事物,通过强制转换为float
执行的比较可能不像使用double
那样“提供信息”,但不太可能产生仅仅是错误的结果。相比之下,请考虑:
double x, y;
float f = x;
如果比较f
和y
,那么感兴趣的是y
与舍入浮点数x
的值的比较,但它是更有可能的是,真正想知道的是,是否知道x
的舍入值,是否可以对x
和y
之间的关系发表任何意见。如果x
为0.1且y
为0.2,则f
会提供足够的信息来说明x
是否大于y
;如果y
是0.100000001,则不会。在后一种情况下,如果两个操作数都被转换为double,则比较将错误地暗示x
更大;如果它们都被转换为浮动,则比较将报告它们无法区分。请注意,将两个操作数转换为double
时的比较结果可能不仅在值在百万分之一范围内时也是错误的;它们可能会偏离数百个数量级,例如x = 1e40且y = 1e300。将f
和y
作为float
进行比较,它们会比较难以区分;将它们比作double
,较小的值会错误地比较较大。
答案 3 :(得分:0)
舍入误差发生在1.1而不是1.5的原因是由于在浮点格式中精确表示像0.1这样的数字所需的位数。事实上,无法准确表达。
请参阅How To Represent 0.1 In Floating Point Arithmetic And Decimal以获取示例,尤其是@paxdiablo的答案。