大十进制数减法不起作用
Big Decimal numbers subtraction is not working
我在下面的程序中遇到了一个简单的问题。在下面的代码中,我只是减去数字,预期输出是“89.50”,但它正在打印 90。我可以知道原因并帮助我获得预期输出的代码。
public class BigDecimal_Prb {
public static void main(String[] args) throws java.lang.Exception
{
MathContext mc = new MathContext(2);
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(BigDecimal.valueOf(30));
list.add(BigDecimal.valueOf(120.00));
BigDecimal [] nums = (BigDecimal[]) list.toArray(new BigDecimal[0]);
BigDecimal reaminingAmt=nums[1].subtract(nums[0], mc);
BigDecimal dedAmt=new BigDecimal(0.5);
BigDecimal ans = reaminingAmt.subtract(dedAmt,mc);
System.out.println(ans);
}
}
减法当然有效,但您所做的其他事情会导致 "unexpected" 结果。
一个MathContext
包含两个主要元素:精度和舍入模式.我猜您了解 舍入模式 ,但不了解 精度 。
精度是BigDecimal
的有效数字的个数。换句话说,如果您将其设置为 2
,您可以预期该数字将四舍五入为两位数,即 90
。如果你想要小数点后一定位数,使用比例:
BigDecimal ans = reaminingAmt.subtract(dedAmt).setScale(2);
是的。终于明白了
不,这不是缩放问题。我发现的 "solution" 具有改变 BigDecimal.toString() 方法结果的副作用。但是,setScale() 的目的是微调对 BigDecimal 值执行的内部计算的结果。如果您只希望 BigDecimal 的小数位数为 2,因为这是计算结果可接受的全部,没关系,请设置小数位数。但是,如果您使用 setScale() 以便您的输出显示“120.00”而不是“120.0”,那么您使用了错误的方法并且出于错误的原因而这样做,IMO。
如果您需要 2 的比例,请将所有实例创建更改为使用 BigDecimal(String) 构造函数。这将保留 .00 部分,然后您将获得您一直在寻找的 2 的比例。
public class BigDecimal_Prb {
public static void main(String[] args) throws java.lang.Exception
{
MathContext mc = new MathContext(4, RoundingMode.HALF_DOWN);
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(BigDecimal.valueOf(30));
list.add(BigDecimal.valueOf(120.00));
BigDecimal [] nums = (BigDecimal[]) list.toArray(new BigDecimal[0]);
BigDecimal reaminingAmt=nums[1].subtract(nums[0], mc);
BigDecimal dedAmt=new BigDecimal(0.5);
BigDecimal ans = reaminingAmt.subtract(dedAmt,mc).setScale(2, RoundingMode.HALF_DOWN);
System.out.println(ans.toString());
}
}
我在下面的程序中遇到了一个简单的问题。在下面的代码中,我只是减去数字,预期输出是“89.50”,但它正在打印 90。我可以知道原因并帮助我获得预期输出的代码。
public class BigDecimal_Prb {
public static void main(String[] args) throws java.lang.Exception
{
MathContext mc = new MathContext(2);
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(BigDecimal.valueOf(30));
list.add(BigDecimal.valueOf(120.00));
BigDecimal [] nums = (BigDecimal[]) list.toArray(new BigDecimal[0]);
BigDecimal reaminingAmt=nums[1].subtract(nums[0], mc);
BigDecimal dedAmt=new BigDecimal(0.5);
BigDecimal ans = reaminingAmt.subtract(dedAmt,mc);
System.out.println(ans);
}
}
减法当然有效,但您所做的其他事情会导致 "unexpected" 结果。
一个MathContext
包含两个主要元素:精度和舍入模式.我猜您了解 舍入模式 ,但不了解 精度 。
精度是BigDecimal
的有效数字的个数。换句话说,如果您将其设置为 2
,您可以预期该数字将四舍五入为两位数,即 90
。如果你想要小数点后一定位数,使用比例:
BigDecimal ans = reaminingAmt.subtract(dedAmt).setScale(2);
是的。终于明白了
不,这不是缩放问题。我发现的 "solution" 具有改变 BigDecimal.toString() 方法结果的副作用。但是,setScale() 的目的是微调对 BigDecimal 值执行的内部计算的结果。如果您只希望 BigDecimal 的小数位数为 2,因为这是计算结果可接受的全部,没关系,请设置小数位数。但是,如果您使用 setScale() 以便您的输出显示“120.00”而不是“120.0”,那么您使用了错误的方法并且出于错误的原因而这样做,IMO。
如果您需要 2 的比例,请将所有实例创建更改为使用 BigDecimal(String) 构造函数。这将保留 .00 部分,然后您将获得您一直在寻找的 2 的比例。
public class BigDecimal_Prb {
public static void main(String[] args) throws java.lang.Exception
{
MathContext mc = new MathContext(4, RoundingMode.HALF_DOWN);
List<BigDecimal> list = new ArrayList<BigDecimal>();
list.add(BigDecimal.valueOf(30));
list.add(BigDecimal.valueOf(120.00));
BigDecimal [] nums = (BigDecimal[]) list.toArray(new BigDecimal[0]);
BigDecimal reaminingAmt=nums[1].subtract(nums[0], mc);
BigDecimal dedAmt=new BigDecimal(0.5);
BigDecimal ans = reaminingAmt.subtract(dedAmt,mc).setScale(2, RoundingMode.HALF_DOWN);
System.out.println(ans.toString());
}
}