检查浮点变量是不是为整数的最可靠方法是啥?
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 值的 range 和 precision。这完全取决于您要达到的目标。
Guffa 有一个很好的方法,它使用允许的精度范围进行 int 比较。
【讨论】:
【参考方案6】:整数可以精确地以浮点表示形式表示,因此如果您正在检查一个精确的整数,其中任何一个都应该工作(我个人会使用第一个...)
【讨论】:
以上是关于检查浮点变量是不是为整数的最可靠方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章