Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java’;什么是大十进制?_Java_Bigdecimal - Fatal编程技术网

如何使用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)会创建一个与
    0.1
    完全相等的BigDecimal(未标度值
    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