检查浮点变量是不是为整数的最可靠方法是啥?

Posted

技术标签:

【中文标题】检查浮点变量是不是为整数的最可靠方法是啥?【英文标题】:What is the most reliable way of checking if a floating point variable is an integer?检查浮点变量是否为整数的最可靠方法是什么? 【发布时间】:2009-03-12 12:21:38 【问题描述】:

我可以想到几种方法,例如。

Convert.ToInt32(floatingPoint) - floatingPoint == 0;
Math.Truncate(floatingPoint) - floatingPoint == 0;
floatingPoint % 1 == 0;
Math.Floor(floatingPoint) == floatingPoint;
//etc...

但是哪种方法最可靠?

【问题讨论】:

【参考方案1】:

您不应该检查是否完全等于零,因为浮点数通常只包含与您分配给它的数字最接近的可能近似值。

例如,该类型可以表示的最接近 42 的值可能是 42.00000000000000662,您仍然希望将其计为整数值。

取该值和舍入值之间的差,然后取其绝对值(使其不是负数)并与一个较小的值进行比较:

if (Math.Abs(Math.Round(floatingPoint) - floatingPoint) < 0.000001) ...

【讨论】:

整数可以用浮点表示法精确表示。您的 42.00000000000000662 示例根本不可能发生。 这不是一个好主意。最终连续位浮点表示之间的差异会大于0.5,然后就不清楚该数字应该表示什么整数了。 @Jimmy:那不是真的。尝试在单精度浮点实现中精确表示 2^31-1。【参考方案2】:

浮点数不能精确表示某些整数,所以没有真正可靠的方法。具体来说,任何大于 2^24 的int 都不能用float 精确表示。唉,这是您为使用浮点表示所付出的一部分代价!

有关您应该注意的各种浮点问题的精彩总结,建议您查看"What Every Computer Scientist Should Know About Floating-Point Arithmetic"。

【讨论】:

【参考方案3】:

无论可靠性如何,取模方法看起来都易于理解(无需阅读任何规范)且速度快(无需函数调用)。

【讨论】:

【参考方案4】:

您将遇到浮点数只是近似值的经典问题。如果你这样做:

floatingPoint = 1.0/3.0;
floatingPoint *= 3;

你最终会得到接近但不完全是 1 的东西。

【讨论】:

【参考方案5】:

没有一般可靠的方法。

如果浮点数是先前计算的结果,则它们(大部分)始终是近似值,因此不存在简单的整数等价,正如其他人指出的那样。

您必须考虑您正在处理的 fp 和 int 值的 rangeprecision。这完全取决于您要达到的目标。

Guffa 有一个很好的方法,它使用允许的精度范围进行 int 比较。

【讨论】:

【参考方案6】:

整数可以精确地以浮点表示形式表示,因此如果您正在检查一个精确的整数,其中任何一个都应该工作(我个人会使用第一个...)

【讨论】:

以上是关于检查浮点变量是不是为整数的最可靠方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

可靠地确定浮点值向量是不是(数字上)等距

使用 PHP 检查多个值是不是为整数的最简单方法是啥?

AWS Amplify iOS:查找用户是不是登录的最可靠方法是啥

整数二分+浮点二分

C语言中float是啥意思

c语言中定义浮点变量输入用的整数会报错吗