2012-10-26 50 views
1

我知道計算機不能精確表示非整數。所以當我在java中添加2個雙打例如:java雙重計算

控制檯打印出來1724.6399999999999

但爲什麼724.64d + 100d724.64d + 10000d

控制檯打印出824.64和10724.64分開?

有沒有辦法知道我在什麼條件下加2個雙打時,總數是確切的數字?

我問的原因是因爲我們的舊程序使用雙重計算。並使用雙重比較來驗證數字。 例如:讓我們說總爲1849.64,全部加起來的投入金額必須等於總這是1849.64

input 1: 724.64 
input 2: 1125 

將無法​​正常工作,因爲總和將1849.6399999999999

但如果我們輸入這樣下面的工作,總和是1849.64

input 1: 24.64 
input 2: 1825 

所以如何找到那些工作組合? 請注意,我無法訪問這個特定的非常舊的程序。當驗證失敗時,我們必須像第二個輸入組合一樣手動查找。 謝謝。

+0

您必須在這裏接受一定數量的錯誤。 – Zavior

+1

如果你想知道哪些數字在Java中有確切的表示形式,你將不得不瞭解Java語言規範,項目4.5.3指向IEEE 754.那裏有很多具體的本科數學。但是,除非你開發自己的編程語言,否則沒什麼意義。 –

+0

我想找出一種快速方法來手動更改輸入組合以供我們的客戶通過驗證。我無權將代碼更改爲舊程序。 – huahua

回答

1

浮點數不代表小數點中的數字,但是在二進制系統中,顯然它們僅具有有限精度,因此十進制系統表示的精確值與浮點數之間存在不匹配可以代表。你不能指望它這樣做。

+0

我知道某些數字不能完全用二進制表示,就像某些數字不能用十進制表示,比如π。我現在唯一的選擇是猜測通過驗證的其他組合。我想知道是否有公會會做這樣的猜測?有時我們接到客戶電話,他們抱怨這種驗證失敗的東西,我們只需告訴他們嘗試輸入這個號碼和那個號碼。 – huahua

+0

轉到[這個頁面](http://www.h-schmidt.net/FloatConverter/IEEE754.html),他們有一個Java小應用程序來設置每個單獨的位在'雙'。所有在尾數右邊都有零的數字將更容易用十進制表示。仔細研究它,看看它是如何工作的。 –

+0

很好的參考。謝謝 – huahua

1
BigDecimal bigDecimal = new BigDecimal(724.64); 
bigDecimal = bigDecimal.add(new BigDecimal(1000.0)); 
System.out.println(bigDecimal.floatValue());<--Works fine 
System.out.println(bigDecimal.doubleValue());<--Works as mentioned in Question 

輸出:

1724.64 
1724.6399999999999 

在第一種情況下,它的工作原理,因爲narrowing primitive conversion發生。但是對於浮點數字,您將不得不接受並接受它。

正如我所說的原因,它是有效的原語

double d = 724.64; 
double d1 = 1000.0; 
System.out.println(d + d1); 
System.out.println((float) (d + d1)); 

輸出:

1724.64 
1724.6399999999999 
+0

謝謝抱歉忘記提及我沒有訪問舊程序的代碼 – huahua

+0

我想這行:System.out.println((float)(d + d1));正在縮小原始轉換。它將double轉換爲float,縮小了精度。 – huahua

0

,而不是試圖確定什麼條件導致精確或不精確的計算考慮使用BigDecimal針對這些情況。

+0

它是生產支持的東西,我不能更改代碼。 – huahua

0

如果比較的問題,作爲一種解決方法,我會建議在字符串中的數字與2位小數格式和舍入完成,然後比較字符串:

 double expectNum = 1849.64; 
     double resultNum = 1849.639999; 

     String expectedString = String.format("%.2g%n", expectNum); 
     String resultString = String.format("%.2g%n", resultNum); 

     if(expectedString.equals(resultString)){ 
      //result matched 
      //return true; 
     }else{ 
      //return false; 
     } 
+0

不回答問題。 – EJP

+0

@EJP:我在開頭就提到過。其解決方案的工作進行比較。 –

+0

他沒有控制源代碼。他正在尋找可用於現有比較的測試數據。沒有答案。 – EJP

1

要回答你的最後一個問題,一個如果小數部分是2的負冪,例如零,1/2,1/4,1/16,...,在其他一些情況下會出現,就像您發佈的那些情況一樣,如果您使用它將它們轉換爲十進制的API(例如System.out.println())進行舍入或截斷,並且值接近足以使舍入或截斷產生預期的答案。

+0

那麼如何快速定位一些其他組合以便使總和爲1849.64。如:輸入1:24.64輸入2:1825。或者我們只能做一個隨機猜測? – huahua