代码之家  ›  专栏  ›  技术社区  ›  mrjbq7

更快地实现math.round?

  •  6
  • mrjbq7  · 技术社区  · 16 年前

    这个代码有什么缺点吗?它似乎是 java.lang.Math.round ?

    public static long round(double d) {
    
        if (d > 0) {
            return (long) (d + 0.5d);
        } else {
            return (long) (d - 0.5d);
        }
    }
    

    它利用了在Java中截断长循环为零的事实。

    3 回复  |  直到 13 年前
        1
  •  15
  •   Kristian    16 年前

    有一些 special cases 内置方法处理的,代码不处理的。从文档中:

    • 如果参数是 NaN ,结果为0。
    • 如果参数为负无穷大或任何小于或等于的值 Integer.MIN_VALUE ,结果等于 integer.min_值 .
    • 如果参数为正无穷大或任何大于或的值 等于 Integer.MAX_VALUE ,结果等于 integer.max_值 .
        2
  •  5
  •   Jonathan Feinberg    16 年前

    是的,你没有考虑到下溢或溢出。从实际意义上讲,这对您的应用程序来说可能并不重要。

        3
  •  3
  •   Community Mohan Dere    9 年前

    我一直在测试这个,有一个关键的潜在缺点还没有在这里描述:你正在改变 rounding tie-breaking 方法。

    Math.round() 实现“舍入一半”规则,而 round() 方法实现了“舍入半离零”规则。

    例如:

    • Math.round(-0.5d) = & gt; 0L
    • Your.round(-0.5d) = & gt; -1L

    这对您来说可能是一个问题,也可能不是问题,但是您应该理解,上面的方法并不是替代 数学循环() 即使在已经概述了NaN和Infinity的考虑之后。

    另一个相关问题: Rounding negative numbers in Java

    至于性能,毫无疑问,上述方法比 数学循环() -对于随机生成的正值和负值,它在大约35%的时间内运行。在紧密循环中调用此方法时,这是一个值得优化的方法。如果只给出正值(可能是因为CPU使用了 branch prediction .

    数学循环() 最终由本机JNI调用实现,这可能是性能差异的原因。 This Sun/Oracle bug 建议在J6U22中可能有纯Java版本,但我看不到哪里,确实如此。 数学循环() 在我的测试中,J6U23的性能与J6U16相似。我没有在其他版本上测试过。

    推荐文章