【问题标题】: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...

但是哪种方法最可靠?

【问题讨论】:

    标签: c# floating-point isinteger


    【解决方案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】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-11-03
              • 2011-08-13
              • 1970-01-01
              • 1970-01-01
              • 2013-11-29
              • 2017-08-23
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多