提问人:Destructor 提问时间:4/30/2015 更新时间:10/16/2017 访问量:911
为什么浮点比较在不同的编译器上给出不同的输出?[复制]
Why floating point comparisons gives different outputs on different compiler? [duplicate]
问:
我正在读这篇文章。它包含以下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 位: 否则 IF
5) MSVS 2010:ELSE IF,但编译时发出警告
警告 1 警告 C4305:“initializing”:从“double”截断为 “浮动”
这里到底发生了什么?程序有什么问题?是否发生了实现定义的行为?
请帮帮我。
答:
浮点数可以用以下形式表示:
[标志][尾数] * 2[指数]
因此,当内存中的空间较少时,会出现舍入或相对错误。
来自维基:
单精度浮点格式是一种计算机数字格式,它在计算机内存中占用 4 个字节(32 位),并使用浮点数表示宽动态范围的值。
IEEE 754 标准将二进制文件32 指定为:
Sign bit: 1 bit
Exponent width: 8 bits
Significand precision: 24 bits (23 explicitly stored)
这提供了 6 到 9 个有效十进制数字的精度(如果 最多 6 位有效小数的十进制字符串转换为 IEEE 754 单精度,然后转换回相同数量的 有效十进制,则最终字符串应与原始字符串匹配; 如果将 IEEE 754 单精度转换为十进制字符串 至少有 9 个有效小数,然后转换回单数, 那么最终的数字必须与原始数字 [4]) 匹配。
更大(更多位)的浮点表示形式可实现更高的精度。
浮点数学并不精确。像 0.1 这样的简单值不能用二进制浮点数精确表示,浮点数的有限精度意味着运算顺序的微小变化可能会改变结果。必读:
IEEE 标准将异常分为 5 类:溢出、下溢、除以零、无效操作和不准确。每个异常类都有一个单独的状态标志。前三个例外的含义是不言而喻的。无效操作包括表 D-3 中列出的情况,以及涉及 NaN 的任何比较。
评论
上一个:浮点加法/乘法/除法
下一个:平均浮点数时保持精度
评论
ELSE
ELSE
float
double
float