我正在阅读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");
}
文章说
上述程序的输出是“ELSE IF”,表示“x == 0.1“返回false,表达式”x == 0.1f“返回true。
但我在不同的编译器上尝试过它。得到不同的产出:
以下是各种IDE的输出。
1)Orwell Dev C ++:ELSE
2)代码块13.12:ELSE IF但在编译期间它会发出以下警告。
警告:将浮点数与==或!=进行比较是不安全的。
为什么这种比较不安全?
3)Ideone.com:ELSE IF(见run:http://ideone.com/VOE3E0)
4)TDM GCC 32位:ELSE IF
5)MSVS 2010:ELSE IF但是会发出警告
警告1警告C4305:'初始化':从'double'截断到 '浮动'
这里到底发生了什么?该计划有什么问题?它是否实现了定义的行为?
请帮帮我。
答案 0 :(得分:2)
浮点数可以用以下形式表示:
[sign] [尾数] * 2 [指数]
当内存空间较小时,会出现舍入或相对错误。
来自wiki:
单精度浮点格式是计算机数字格式,在计算机内存中占用 4字节(32位),并使用浮点表示宽动态范围的值。
IEEE 754标准将binary32指定为:
Sign bit: 1 bit
Exponent width: 8 bits
Significand precision: 24 bits (23 explicitly stored)
这从 6到9有效十进制数字精度(如果a 最多6个有效小数的十进制字符串转换为IEEE 754单精度然后转换回相同的数量 有效小数,则最终字符串应与原始字符串匹配; 如果IEEE 754单精度转换为十进制字符串 至少有9个有效小数,然后转换回单个, 那么最终的数字必须与原来的[4]相匹配。
更大(更多位)的浮点表示允许更高的精度。
浮点数学并不准确。像0.1这样的简单值无法使用二进制浮点数精确表示,浮点数的有限精度意味着操作顺序的微小变化可能会改变结果。必须阅读:
What Every Computer Scientist Should Know About Floating-Point Arithmetic
IEEE标准将异常分为5类:溢出,下溢,除零,无效操作和不精确。每个异常类都有一个单独的状态标志。前三个例外的含义是不言而喻的。无效操作涵盖表D-3中列出的情况,以及涉及NaN的任何比较。