Why floating point comparisons gives different outputs on different compiler? [duplicate]

柔情痞子 提交于 2019-12-11 02:30:47

问题


I was reading this. It contains following C program.

#include<stdio.h>
int main()
{
    float x = 0.1;
    if (x == 0.1)
        printf("IF");
    else if (x == 0.1f)
        printf("ELSE IF");
    else
        printf("ELSE");
}

The article says that

The output of above program is “ELSE IF” which means the expression “x == 0.1″ returns false and expression “x == 0.1f” returns true.

But I tried it on different compilers & getting different outputs:

Here is the outputs on various IDEs.

1) Orwell Dev C++: ELSE

2) Code Blocks 13.12: ELSE IF but it gives following warnings during compilation.

warning: comparing floating point with == or != is unsafe.

Why this comparison is unsafe?

3) Ideone.com: ELSE IF (see run: http://ideone.com/VOE3E0)

4) TDM GCC 32 bit: ELSE IF

5) MSVS 2010: ELSE IF but compiles with warning

Warning 1 warning C4305: 'initializing' : truncation from 'double' to 'float'

What is exactly happening here? What's wrong with the program? Is it implementation defined behavior occurring?

Please help me.


回答1:


A floating point number maybe represented in the following form:

[sign] [mantissa] * 2[exponent]

So there will be rounding or relative errors when the space is less in memory.

From wiki:

Single-precision floating-point format is a computer number format that occupies 4 bytes (32 bits) in computer memory and represents a wide dynamic range of values by using a floating point.

The IEEE 754 standard specifies a binary32 as having:

Sign bit: 1 bit
Exponent width: 8 bits
Significand precision: 24 bits (23 explicitly stored)

This gives from 6 to 9 significant decimal digits precision (if a decimal string with at most 6 significant decimal is converted to IEEE 754 single precision and then converted back to the same number of significant decimal, then the final string should match the original; and if an IEEE 754 single precision is converted to a decimal string with at least 9 significant decimal and then converted back to single, then the final number must match the original [4]).

Larger (more bits) floating point representations allow for greater precision.

Floating point math is not exact. Simple values like 0.1 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. A must read:

What Every Computer Scientist Should Know About Floating-Point Arithmetic

The IEEE standard divides exceptions into 5 classes: overflow, underflow, division by zero, invalid operation and inexact. There is a separate status flag for each class of exception. The meaning of the first three exceptions is self-evident. Invalid operation covers the situations listed in TABLE D-3, and any comparison that involves a NaN.



来源:https://stackoverflow.com/questions/29962813/why-floating-point-comparisons-gives-different-outputs-on-different-compiler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!