BigDecimal.Divide 给出了错误的结果
BigDecimal.Divide gives incorrect result
我在使用 BigDecimal 执行除法时得到不正确的结果。
数字 1 = 221500.0
数字 2 = 12.0
这是我的代码片段:
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.33333333332
如果我使用它提供的计算器执行相同的计算
18458.333333333333333333333333333
让我知道处理 BigDecimal 中的比例的任何问题。如果有人让我知道如何使用计算器得出相同的结果,那将会很有帮助。
您要求 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)
.
设置d1
和d2
的比例好像没什么意思
除非明确需要,否则尽可能晚进行舍入。
有些事情你应该做不同的事情。
如您所知,BigDecimal 是一个很棒的工具,因为:
它可以精确地保留十进制数字,不像任何浮点表示,例如 double 或 float
它可以处理任意大的十进制数,不像 int、double 和 float
然而,要让它发挥作用,您应该牢记以下几点:
将值设置为 BigDecimal 时,始终 使用字符串表示形式,因为只有字符串表示形式会处理小数精度。例如, new BigDecimal(String.valueOf(number1)) 是个坏主意,如果数字是双精度数(无法处理精确的小数),那么您会将不精确的数字转换为 BigDecimal。
创建 BigDecimal 时不限制精度。通常 BigDecimal 将保持输入的精度,即 new 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
比计算器好很多,不是吗? :)
我在使用 BigDecimal 执行除法时得到不正确的结果。 数字 1 = 221500.0 数字 2 = 12.0 这是我的代码片段:
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.33333333332
如果我使用它提供的计算器执行相同的计算 18458.333333333333333333333333333
让我知道处理 BigDecimal 中的比例的任何问题。如果有人让我知道如何使用计算器得出相同的结果,那将会很有帮助。
您要求 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)
.
设置d1
和d2
的比例好像没什么意思
除非明确需要,否则尽可能晚进行舍入。
有些事情你应该做不同的事情。
如您所知,BigDecimal 是一个很棒的工具,因为:
它可以精确地保留十进制数字,不像任何浮点表示,例如 double 或 float
它可以处理任意大的十进制数,不像 int、double 和 float
然而,要让它发挥作用,您应该牢记以下几点:
将值设置为 BigDecimal 时,始终 使用字符串表示形式,因为只有字符串表示形式会处理小数精度。例如, new BigDecimal(String.valueOf(number1)) 是个坏主意,如果数字是双精度数(无法处理精确的小数),那么您会将不精确的数字转换为 BigDecimal。
创建 BigDecimal 时不限制精度。通常 BigDecimal 将保持输入的精度,即 new 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
比计算器好很多,不是吗? :)