2013-11-03 25 views
-3

代碼:爲什麼BigDecimal的精度不夠準確?

BigDecimal test = new BigDecimal(3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199); 
System.out.println(test.toPlainString()); 

這裏是輸出:

3.141592653589793115997963468544185161590576171875 

我調試它,並test的存儲器中的3.141592653589793115997963468544185161590576171875太超值了。這很有趣,因爲只有第一部分是正確的:3.141592653589793

+1

我意識到問題在於數字文字被視爲雙重字符。解決方法是將數字用引號括起來以將字符串傳遞給BigDecimal的構造函數。我將把這個問題留給任何人在將來閱讀。 – user2950075

+0

因爲3.14 ...文字最初編碼爲「double」。 –

+0

@ user2950075沒錯,我只是想將其作爲答案發布。 – arshajii

回答

1
new BigDecimal(double) 

構造函數會得到不精確的double

嘗試使用String基於構造來代替:

new BigDecimal("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199") 
0

引號試試圍繞在構造函數的值:

BigDecimal test = new BigDecimal("3.14159265358979323846264 .... "); 

因爲它是此刻的你真的將低級精度Java double值,不是全精度數字

5

您的3.1415...是一個雙重字面,它得到了trun在編譯之前,編譯器的精度提高了兩倍,即使在BigDecimal甚至可以看到它。將引號放在它的周圍,並將其作爲字符串傳遞。

0

您可以利用the constructor which takes a double建設BigDecimal對象。因此,在構建BigDecimal對象之前,Java會將您的號碼轉換爲double

的Javadoc說:

此構造的結果可能是有些不可預測。有人可能會認爲在Java中編寫新的BigDecimal(0.1)會創建一個正好等於0.1的BigDecimal(非縮放值爲1,標度爲1),但實際上它等於0.1000000000000000055511151231257827021181583404541015625。

嘗試使用another constructor,例如需要String

0

BigDecimal足夠準確。但是,您提供的數字正被轉換爲不準確的int或long。僅僅因爲你犯了一個較長的數字,並不意味着它被採取與精度:

BigDecimal test1 = new BigDecimal(3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199); 
System.out.println(test1.toPlainString()); 

輸出是:

3.141592653589793115997963468544185161590576171875 

引號試試這個,請將輸入使之充分精度被捕獲並它不會由編譯器變換爲int或長:

BigDecimal test2 = new BigDecimal("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199"); 
System.out.println(test2.toPlainString()); 

的,TEST2的輸出將是全精度:

3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199