如何使用Java’;什么是大十进制?
据我所知,如何使用Java’;什么是大十进制?,java,bigdecimal,Java,Bigdecimal,据我所知,BigDecimal用于正确处理小数位数固定的数字(即货币)。下面是我写的一个小程序: import java.math.*; 公共班机{ 公共静态void main(字符串[]args){ BigDecimal a=新的BigDecimal(11.22,新的MathContext(2,取整模式,向上取整)); 系统输出打印项次(“a:+a”); BigDecimal b=a.add(新的BigDecimal(0.04)); System.out.println(“b:+b”); }
BigDecimal
用于正确处理小数位数固定的数字(即货币)。下面是我写的一个小程序:
import java.math.*;
公共班机{
公共静态void main(字符串[]args){
BigDecimal a=新的BigDecimal(11.22,新的MathContext(2,取整模式,向上取整));
系统输出打印项次(“a:+a”);
BigDecimal b=a.add(新的BigDecimal(0.04));
System.out.println(“b:+b”);
}
}
我希望看到:
a: 11.22
b: 11.26
但我得到的是:
a: 11
b: 11.040000000000000000832667268468867405317723751068115234375
我将a
设置为小数点后两位,但它都不会打印它们,甚至会忘记它们并舍入为纯整数。为什么b
应加上0.04,并从a
中知道小数点后两位。这至少是我所期望的
使用bigdecimedit:和两个双精度值作为输入以及已知的小数位数,如何正确解决此问题?[也就是说,因为API只提供这两个双精度值。](我知道还有其他方法可以可靠地使用货币进行计算(从使用int
以美分计算开始),但这不在我的问题范围之内。)不要使用
- 此构造函数的结果可能有些不可预测。人们可能会假设,在Java中编写新的BigDecimal(0.1)会创建一个与
完全相等的BigDecimal(未标度值0.1
,标度为1
),但实际上它等于1
。这是因为0.10000000000000055115123125782702118158340451015625
不能精确地表示为0.1
(或者,就此而言,表示为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于double
,尽管如此0.1
a: 11.22
b: 11.26
正如@Progman所写的,使用double构造函数将创建double值的精确十进制表示,这是正确的 但是,您得到11而不是11.22的原因是您已将MathContext的精度设置为2。
精度是使用的位数,而不是小数位数。因此,如果您将代码更改为使用4作为精度,那么您将获得输出
a: 11.22
b: 11.260000000000000000832667268468867405317723751068115234375
仍然存在使用双精度值的问题,但是现在小数位数更多了
文档中将精度定义为位数使用双精度值而不是字符串作为
BigDecimal
的参数的问题在于,它们大多不精确,会导致重复的十进制扩展。事实上,只有分母中为5
和/或2
幂的浮点数才能精确表示为浮点数或双精度浮点数(例如1/20=.05 1/4=.25,1/5=.2)。这是因为5
和2
是基10
的唯一基本因子,将返回分数的有限(即非重复)展开式。任何其他值都会导致重复的十进制扩展(例如,1/3=.3333,1/6=.16666666),这就是导致问题的原因
通过指定字符串而不是双精度字符串,BigDecimal
可以对预期的期望值进行操作,而不是对二进制值进行限制或控制
如果你的价值观如下
BigDecimal a = new BigDecimal(11.25);
System.out.println("a: " + a);
BigDecimal b = a.add(new BigDecimal(.50));
System.out.println("b: " + b);
结果可能是
11.25
11.75
因为分数部分和结果和只有5和2作为它们的除数
因此,在初始化BigDecimal
对象时,应该指定浮点值的字符串表示形式
有关浮点数的内部表示形式的更多信息,请查看
11.25
11.75