2013-11-03 26 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