2009-11-17 41 views
5

這段代碼有沒有什麼缺點,看起來是java.lang.Math.round更快(更正確)的版本?更快執行Math.round?

public static long round(double d) { 

    if (d > 0) { 
     return (long) (d + 0.5d); 
    } else { 
     return (long) (d - 0.5d); 
    } 
} 

它需要的事實,即,在Java中,截斷長回合零。

+2

@TrueWill:如果它整齊地放在一個正確命名的函數中......它真的很重要嗎?也許它正在用於數學密集型計劃。 – Sivvy 2009-11-17 18:20:16

+0

很少有人會爲從1開始的方法找到更快的方法。0,同時保持原始方法的100%一致性。 – TofuBeer 2009-11-17 18:32:24

+0

絕對是一個微型優化,在當地意義上是值得的。 - 但這些不推薦用於一般用途。 – mrjbq7 2009-11-17 18:53:20

回答

15

有一些special cases內置方法處理,你的代碼不處理。從文檔:

  • 如果參數爲NaN,結果爲0
  • 如果參數爲負無窮大或小於或等於的Integer.MIN_VALUE值的任何值,則結果等於值Integer.MIN_VALUE
  • 如果自變量爲正無窮大或大於或等於Integer.MAX_VALUE的值的任何值,則結果等於Integer.MAX_VALUE的值。
5

是;你沒有考慮下溢或溢出。從實際的角度來說,這可能對您的應用程序無關緊要。

3

我一直在測試這個,有一個關鍵的潛在缺點,這裏還沒有描述:您正在更改rounding tie-breaking方法。

Math.round()實現了「圓形半邊」規則,而您的round()方法實現了「圓形零距離」規則。

例如:

  • Math.round(-0.5d) =>0L
  • Your.round(-0.5d) =>-1L

這可能也可能不適合你有問題,但應瞭解的是,上述方法是不是對Math.round()的直接替換,即使在已經列出NaN和無限大考慮之後。

另一個相關問題:Rounding negative numbers in Java

至於性能,這是毫無疑問的是,上述方法是顯著快於Math.round() - 它運行在的時間爲隨機生成的正和負值約35%。在緊密循環中調用此方法時,這可能是一種有價值的優化。當僅給出正值時,它甚至更好(25%的運行時間),可能是因爲CPU使用branch prediction

Math.round()最終由本地JNI調用實現,這可能是性能差異的原因。 This Sun/Oracle bug表明在j6u22中可能存在純Java版本,但我無法看到j6u23中的哪個位置,實際上Math.round()與我在測試中的j6u16相似。我沒有在其他版本上測試過。