use*_*696 1 c++ floating-point double floating-point-precision
根据这篇文章,当比较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;
}
Run Code Online (Sandbox Code Playgroud)
我还打印了值的十六进制表示法.它们在两种情况下都不同.我的编译器是Visual Studio 2005
你能解释一下这个输出吗?谢谢.
Pet*_*ker 10
float f = 1.1;
double d = 1.1;
if (f == d)
Run Code Online (Sandbox Code Playgroud)
在此比较中,值f被提升为type double.您所看到的问题不是在比较中,而是在初始化中.1.1不能完全表示为浮点值,因此存储在f和d中的值是可以表示的最接近的值.但是float并且double是不同的大小,因此具有不同数量的有效位.当值in f被提升为时double,没有办法找回存储该值时丢失的额外位,因此最终会在额外位中使用全零.那些零位与位中的位不匹配d,因此比较为假.比较成功的原因1.5是1.5 可以完全表示为afloat并作为double; 它的低位有一堆零,所以当促销添加零时,结果与double表示相同.
我找到了一个关于你遇到的问题的正确解释以及一些解决方案.
请参阅比较浮点值有多危险?
请注意,请记住,某些值无法在IEEE 754浮点表示中完全表示.使用值1.5的相同示例将按照您的预期进行比较,因为存在1.5的完美表示而没有任何数据丢失.但是,32位和64位的1.1实际上是不同的值,因为IEEE 754标准不能完美地表示1.1.
double a = 1.1 --> 0x3FF199999999999A
Run Code Online (Sandbox Code Playgroud)
近似表示= 1.10000000000000008881784197001
float b = 1.1 --> 0x3f8ccccd
Run Code Online (Sandbox Code Playgroud)
近似表示= 1.10000002384185791015625
如您所见,这两个值是不同的.
此外,除非您在某些有限的内存类型环境中工作,否则使用浮点数有点无意义.只需使用双打并避免头痛.
如果您不清楚为什么某些值无法准确表示,请参阅有关如何将小数转换为浮点的教程.
这是一个:http://class.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html