我正在阅读this 。它包含以下C程序。
#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 output of above program is “ELSE IF” which means the expression “x == 0.1″ returns false and expression “x == 0.1f” returns true.
但是我在不同的编译器上尝试过并得到不同的输出:
以下是各种 IDE 上的输出。
1) Orwell Dev C++:ELSE
2) 代码块 13.12: ELSE IF 但在编译过程中给出以下警告。
warning: comparing floating point with == or != is unsafe.
为什么这种比较不安全?
3) Ideone.com:ELSE IF(请参阅运行:http://ideone.com/VOE3E0)
4) TDM GCC 32 位:ELSE IF
5) MSVS 2010:ELSE IF 但编译时出现警告
Warning 1 warning C4305: 'initializing' : truncation from 'double' to 'float'
这里到底发生了什么?程序出了什么问题?是否发生了实现定义的行为?
请帮助我。
最佳答案
float 可以用以下形式表示:
[sign] [mantissa] * 2[exponent]
所以当内存空间较小时,就会出现舍入或相对误差。
来自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.
IEEE 754 标准将二进制 32 指定为具有:
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]).
更大(更多位)的浮点表示可以实现更高的精度。
float 学并不精确。像 0.1 这样的简单值无法使用二进制 float 精确表示,并且 float 的有限精度意味着运算顺序的轻微变化可能会改变结果。必读:
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.
关于c - 为什么浮点比较在不同的编译器上给出不同的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29962813/