为什么在浮点比较中,最后一个小数位数为5的浮点值能给出正确的输出,而在其他情况下却不是
Why does the float having 5 as its last decimal digit give the correct output in floating point comparisons,while in other cases it is not?
我已经问过这个问题,但我不清楚这个特定子部分的答案。请参阅下面的代码:
float f=2.5;
if (f==2.5)
printf("abc");
else
printf("xyz"); //prints abc
我知道,如果我们取2.2
而不是2.5
,它会输出相反的结果,因为float取为double和浮点数。它们实际上不应该相等吗?我想知道为什么数字的最后一个十进制数字5
会出现异常。
2.5
可以写成并矢有理数,并且给定它的大小也足够小,它可以在IEEE754浮点中精确地表示。2.25
也可以被完美地表示。参考:https://en.wikipedia.org/wiki/Dyadic_rational
浮点数实际上不应等同于
这不过是一条经验法则。使用考虑不周的公差进行任意比较可能是有害的。浮点并没有什么神秘之处。只是它们中的大多数不能用小数表示(这是开发人员倾向于考虑的),仅此而已。
因为它可以表示为2的整数次幂。例如,2.5=5/2=5×(2-1)。这与浮点值的常用表示形式直接匹配。
如果测量一个距离,它是多少毫米?是多一点点还是少一点点?如果你放大你的标尺,它是多少微米?不是多一点还是少一点?
这说明浮点使用位来表示值的近似值,并且不能(不能总是)表示精确值。
数字2.5通过了测试,因为0.5精确地表示为二进制分数。它是2-1。事实上,2的每一个负幂都有5作为它的最后一个数字。以下是的几个例子
2^-1 = 0.5000000000000000
2^-2 = 0.2500000000000000
2^-3 = 0.1250000000000000
2^-4 = 0.0625000000000000
2^-5 = 0.0312500000000000
2^-6 = 0.0156250000000000
2^-7 = 0.0078125000000000
2^-8 = 0.0039062500000000
2^-9 = 0.0019531250000000
2^-10 = 0.0009765625000000
2^-11 = 0.0004882812500000
需要注意的事项:
- C语言的大多数实现都表示浮点数字是2的负幂之和(那么这个和本身就是乘以2的幂)
- 你在上面看到的模式将继续适用于2.这是因为当末端的50除以2时,它总是会产生一个末端有5的数字,而5会再向右小数一位
- 当你将2的负幂的任意组合求和时最小的数字将始终贡献末尾的5数字,并且该5将不会与任何在较大的数字中
所以所有具有精确表示的数字都以5结尾。然而,这并不是说每个以5结尾的数字都有一个精确的表示。例如0.385没有精确的表示,并且将不通过相等性测试。
相关文章:
- 与其他编译器相比,相同的代码在工作室Microsoft提供不同的输出
- 如何在程序执行时查看Valgrind Massif输出(或其他堆分析器)?
- 为什么在其他输出线之间得到"1"输出?
- bcdedit 文件输出不起作用,但其他命令可以
- Java 和其他语言在生成子序列时的输出差异
- VS说"Too few arguments...",但其他编译器给了我正确的输出?
- 字符串流不会输出其他变量吗?
- 为什么在浮点比较中,最后一个小数位数为5的浮点值能给出正确的输出,而在其他情况下却不是
- 如何将OpenCV的输出显示或流式传输到HTML页面或其他一些客户端应用程序
- 哪些数据文件从python(或其他)中读取的C 输出格式更有效
- 最后一行欧普特两个组合输出问题?如果其他语句
- C 链接列表仅输出其他每个元素
- 来自其他字符串的输出文件名
- 如何将opencv和其他dll文件链接到visual studio 2013的输出exe
- 将dll与c++项目中的其他输出文件分离
- 用于循环的C++没有以其他方式输出
- 如何在Qt中显示其他应用程序的输出视频
- GNU Radio没有来自与我自己的OOT块并行的其他块的输出
- Gradle C(本机)任务输出文件(用于其他任务/项目)
- 当键入指定单词作为第一个字母时显示输出,并忽略后面的其他单词