簡體   English   中英

用BigDecimal等效項替換Java數學運算符

[英]Replace Java math operators with BigDecimal equivalents

我有一個程序可以處理Java代碼段,這些代碼段使用標准數學運算符進行doubles運算,如下所示:

double someVal = 25.03;
return (someVal * 3) - 50;

出於原因(主要是舍入錯誤),我想將所有這些代碼片段更改為使用BigDecimal而不是double ,並一路修改數學函數,如下所示:

MathContext mc = MathContext.DECIMAL32;
BigDecimal someVal = new BigDecimal("25.03", mc);
return someVal.multiply(BigDecimal.valueOf(3), mc).subtract(BigDecimal.valueOf(50), mc);

這些代碼片段大部分都非常簡單,但是如果可以的話,我寧願避免使用脆弱的解決方案(例如,正則表達式)。 有相對簡單的方法嗎?

注意我想讓一個程序或代碼執行這些修改(元編程)。 顯然,我有能力手動進行更改,但是壽命太短了。

您可以嘗試使用Google的“ Refaster”,根據本文所述,“ Refaster”是“一種使用普通的,可編譯的Java前后示例來指定Java重構的工具”。

該代碼位於Google error-prone github項目的 core/src/main/java/com/google/errorprone/refaster (它曾經存在於自己的github項目中 。)

但是,這更多是提示而不是答案,因為我從來沒有直接與Refaster一起工作過,也不知道它在像您的示例那樣的基本表達式上的表現如何。 我也不知道它是否適合像您這樣的工具鏈使用,而不是一次性重構(這就是Google傾向於使用它)。 但是它已經得到了積極維護,而且我在過去已經看到它的使用非常有效。

我們使用BigDecimal進行財務計算。 與其他評論一樣,您將在性能上有所下降,並且代碼將很難閱讀。 對性能的影響取決於您將要執行的操作數。 通常,當您的計算鏈較長時,您將面臨雙打取舍問題。 如果您執行c=a+b不會有很多問題,但是如果您執行c+=a+b百萬次,則不會有很多問題。 通過一千次操作,您會注意到bigDecimal比double慢多少,性能測試也是如此。

在更改代碼(尤其是使用除法)時要特別小心,您將必須指定舍入模式和結果的小數位數,這是人們通常不會執行的操作,並且會導致錯誤。

我認為這不僅涉及替換計算邏輯,而且您還需要更改您的域模型,因此我懷疑您是否可以拿出一個腳本在合理的時間內完成操作,因此請手動完成。 好的IDE將為您提供很多幫助。

無論您打算如何轉換代碼,我都建議首先確保所有計算邏輯都包含在單元測試中,並在更改邏輯之前進行單元測試轉換。 即通過用bigDecimals包裝它們來替換值的斷言。 在這種情況下,您將避免愚蠢的鍵入/算法錯誤。

我不會回答您的問題,如何將double從BigDecimal轉換為只想與regaridng分享一些筆記

不要這樣

  • 這極大地提高了可讀性。 您的示例將“ 25.03 * 3-50”轉換為4行代碼。
  • 金融代碼通常使用doublelong for cents。 足夠精確的是,它只是為了避免舍入錯誤而進行適當編程的問題: Java BigDecimal性能如何?
  • 這很可能會極大地影響性能,尤其是在垃圾回收不穩定的情況下,這對於HFT等不可接受: https : //stackoverflow.com/a/1378156/1339987
  • 我不知道您在談論多少代碼,但我確實希望您必須做出很多小的決定。 這減少了有一個公開可用的工具的機會(我是所有人,但肯定不存在),並且增加了找到工具后必須做的配置工作的數量。
  • 除非您有非常好的測試覆蓋范圍,否則出於與您期望它有所改進的相同原因,這將引入錯誤。

這里介紹了以編程方式操作Java源代碼自動生成Java源代碼

您不需要接受這個答案,但是我相信我的建議是正確的,並且認為該問題的其他讀者需要預先了解進行此轉換的情況,這是我發布此未回答內容的理由。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM