如何检查浮点数是否为整数?

5
< p > printf 函数的 %g 能够在浮点数为3.00时显示整数3,并且如果浮点数不是一个整数,它会显示3.01

如果不将数字格式化成字符串,你该如何通过代码实现这一点?


这是 %g,我想是这样,但我不确定你问的是什么。 - Grijesh Chauhan
2
你能重新表达一下问题吗?我不明白你在问什么。 - Praetorian
https://dev59.com/eHVC5IYBdhLWcg3wfhKL - Drew Dormann
将%g的功能放入实际函数中,以便我可以在printf之外使用它。 - user2140285
1个回答

11

没有简单的答案

在浮点数和双精度格式中,整数值确实具有精确的表示。因此,如果它已经是整数,您可以使用:

f == floor(f)

然而,如果你的值是计算的结果,并且其中某个点涉及任何非零小数部分,那么你需要担心可能存在一个非常接近于整数但实际上并不完全相同的情况。你可能想要将其视为整数。

一种可能的方法是:

fabs(f - round(f)) < 0.000001

提到这个话题时,对于纯粹主义者,我们应该注意,int i = f;double i = f;将根据FPU模式进行四舍五入,而round(3)会将半路上的情况向远离零的方向四舍五入。


3
@user2140285 - 要小心。 "Nearly equal" 是一种高级技术。它违反了传递性(几乎等于 b,b 几乎等于 c,并不意味着 a 几乎等于 c),而且它可能掩盖真正的问题,这些问题后来会对你造成影响。 - Pete Becker
1
当使用这种技术进行比较时,您可能会发现在头文件<cmath>中定义的常量FLT_EPSILONDBL_EPSILONLDBL_EPSILON非常方便。 - fish2000
这里有来自Pete Becker和fish2000的好建议。这是一种高级技术。(这也是我说:“这里没有简单的答案”的原因。) - DigitalRoss
1
整数值在浮点和双精度格式中确实有准确的表示。在使用ISO/IEE 754-1985通用模型的现代计算机中,双精度和浮点数都使用有限位数的尾数,例如FLT_MANT_DIG(24)和DBL_MANT_DIG(53)。因此,可以说如果你有24位或53位整数,则表示方式是相同的。 - Konstantin Burlachenko
1
@fish2000:Epsilon是相邻浮点数之间的距离,为1.0。例如,nextafter(1.0, +inf) - 1,即在1.0-1.9999的指数值处为1ulp,但对于任何更大的数量级,它都小于尾数中最后一位的1个单位。因此,除了零(当向下到0.9999999...时),它是双倍数与整数之间可能存在的最小差异量。但对于接近任何其他整数的数字,它比最小舍入误差还要小。浮点错误通常是相对的,而不是绝对的,因为该格式保留了固定数量的有效数字(以二进制表示)。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接