2016-02-23 125 views
0

我在使用BigDecimal执行除法时得到不正确的结果。 NUMBER1 = 221500.0 数字2 = 12.0 这里是我的代码片段:BigDecimal.Divide给出的结果不正确

BigDecimal d1 = new BigDecimal(String.valueOf(number1)).setScale(13, 4); 
BigDecimal d2 = new BigDecimal(String.valueOf(number2)).setScale(13, 4); 
return (d1.divide(d2, 13, 4)).doubleValue(); 

18458.333333333332

,如果我使用计算器它给 18458.333333333333333333333333333

让我知道任何问题进行同样的计算处理BigDecimal中的比例。如果有人让我知道如何与计算器达到相同的结果,这将会有所帮助。

+1

这是正确的结果。你真的需要这么长的结果吗? –

+0

*确切*相同的结果?你的计算器是否吐出适量的3s,或者?实际上有3个无限的数量。 –

+1

由于您需要13个值,BigDecimal正在如何工作。如果您的目的要求“精确的除法结果”,为了比较目的,请乘以某个预先确定的阈值并作为整数进行比较。在你的情况下,'double'不能保持这个值,所以舍入。 –

回答

4

你问了divide()调用13位数的精度,这就是它给你的。

然后,您将其转换为double,并注意double无法处理该精度。

BigDecimal d1 = new BigDecimal(String.valueOf(221500.0)).setScale(13, BigDecimal.ROUND_HALF_UP); 
BigDecimal d2 = new BigDecimal(String.valueOf(12.0)).setScale(13, BigDecimal.ROUND_HALF_UP); 
BigDecimal d3 = d1.divide(d2, 13, BigDecimal.ROUND_HALF_UP); 
System.out.println("BigDecimal: " + d3); 
System.out.println("as double : " + d3.doubleValue()); 

输出

BigDecimal: 18458.3333333333333 
as double : 18458.333333333332 

如果你要扔掉通过BigDecimal获得了额外的精度,为什么不只是做double数学?


在不同的音符:
不要做new BigDecimal(String.valueOf(doubleValue))。使用BigDecimal.valueOf(doubleValue)

设置d1d2的比例似乎没有意义。
除非明确需要,否则尽可能晚回合。

+2

@Andreas在说什么,不要调用.doubleValue()这样做会将您的高精度数字转换为不太精确的双精度 – Arkiliknam

3

有些事情你应该做不同的事情。

正如你已经知道,BigDecimal的是一个伟大的工具,因为:

  • 它可以保留小数位数完全相同,不同于任何浮点表示如浮动

  • 它可以使用任意大的十进制数,不像int,double and float

然而,使其工作时,你应保持几件事情:

  • 设置值时为BigDecimal,总是使用字符串表示,因为只有字符串表示将处理小数精度。例如,新的BigDecimal(String。valueOf(number1))是一个坏主意,如果number是一个double(不能处理精确的小数),那么你将把这个不精确的数字转换为BigDecimal。

  • 创建BigDecimal时不要限制精度。通常BigDecimal会保持输入的精度,即新的BigDecimal(“3.234”)将有3个十进制数字。

  • 请在每次划分后设置roudingMode。有关可能的排队模式,请参阅JavaDoc,HALF_EVEN是常见用例的最佳选择。

  • 设置除法的小数精度,因为除法可能导致无穷的小数位数。

考虑这个例子:

public class BigDecimalTest { 

    public static void main(final String[] args) { 
     final BigDecimal d1 = new BigDecimal("221500"); 
     final BigDecimal d2 = new BigDecimal("12"); 
     final BigDecimal result=d1.divide(d2,30,RoundingMode.HALF_EVEN); 
     System.out.println(result); 
    } 

} 

这给

18458.333333333333333333333333333333

与要求所有的30位小数。随意改变30〜300这给

18458.333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

很多比计算器更好,不是吗? :)