Java,BigDecimal。分工问题

Java,BigDecimal。分工问题,java,division,bigdecimal,Java,Division,Bigdecimal,我试图计算一个百分比“因子”。也就是说,给定20%,将其转换为0.2(我的目的是稍后将值乘以该值,得到20%的值) 无论如何,这个问题与这段代码有关: public static void main(String[] args) { int roundingMode = BigDecimal.ROUND_FLOOR; BigDecimal hundred = new BigDecimal("100"); BigDecimal percentageFactor = null

我试图计算一个百分比“因子”。也就是说,给定20%,将其转换为0.2(我的目的是稍后将值乘以该值,得到20%的值)

无论如何,这个问题与这段代码有关:

public static void main(String[] args) {
    int roundingMode = BigDecimal.ROUND_FLOOR;
    BigDecimal hundred = new BigDecimal("100");
    BigDecimal percentageFactor = null;
    BigDecimal percentage = new BigDecimal("20");
    BigDecimal value = new BigDecimal("500");
    percentageFactor = percentage.divide(hundred, roundingMode);
    float f = percentage.floatValue() / hundred.floatValue();
    f = value.floatValue() * f;
    BigDecimal aux = value.multiply(percentageFactor);
    System.out.println("factor:"+percentageFactor.toString());
    System.out.println("final falue:"+aux.toString());
    System.out.println("Float Value:"+f);       
}
我预计结果会是:

factor: 0.2
final value: 100
float value: 100
而是
percentage.divide(百,取整模式)返回零,因此我得到:

factor:0
final falue:0
Float Value:100.0
我做错了什么?我怎样才能正确地划分两个大小数


顺便说一句,我使用的是
BigDecimal
,因为我要计算货币百分比,所以我想要控制舍入。

新的BigDecimal(“20”)
的刻度是零,因为里面没有小数点。这意味着你的
percentage.divide(百,BigDecimal.ROUND\u loor)
将产生零(实际上是
int(20/100)
0

如果你真的想做分数,可以使用
newbigdecimal(“20.00”)
来正确设置比例,或者使用其他构造函数来专门设置比例

以下是从
20
20.00
的简单更改的输出,以及拼写错误:-)


我认为最好的解决方案是在分割时设置所需的比例:在这种情况下,可能是2

    var hundred = new BigDecimal(100);
    var percentage = new BigDecimal(20);
    var value = new BigDecimal(500);
    
    var percentageFactor = 
        percentage.divide(hundred,2, BigDecimal.ROUND_HALF_UP);
    
    value = value.multiply(percentageFactor);
    System.out.println("final value:"+ value);
最终值:
100.00

乘法使用因子(0+2)的刻度,但也可以指定


我会使用
四舍五入(在我的立法中)进行会计核算,或者使用
四舍五入(在统计中)进行四舍五入模式。

float只有6位精度,几乎不是一个好的选择,我建议你改为使用double。(在某些情况下,BigDecimal可能更好)

原因代码中的系数是0,而不是0.2是因为

  • 您已将RoundingMode设置为FLOOR(即向下取整),并且
  • 您的
    percentage
    变量的隐式刻度为0(从整数初始化的任何
    BigDecimal
    s,未指定刻度,其刻度为0)
  • 所以,当你调用divide时,你是在对任何小数进行舍入,并且你保持了0的刻度,因此0.2被舍入为0

    要获得正确的号码,您可以

  • 明确指定比例,或
  • 由于您知道要除以100,因此可以使用
    BigDecimal#divide(BigDecimal)
    方法代替(不提供scale或RoundingMethod)。在您的情况下,该方法不会抛出
    算术异常
    ,因为不可能有非终止小数(想想20/100=0.2,20/10000=0.002-小数总是在除以100时终止)
    但是,如果要与另一个数字(比如3)进行除法,则需要指定小数位数,因为可能存在非终止小数(想想10/3=3.3333333…)

    如果要控制舍入,则不应使用浮点数字,既不能使用浮点数字,也不能使用双精度数字。坚持使用BigDecimal。通常只有最终结果需要有控制的舍入,因此您使用BigDecimal只是为了对结果进行舍入(或一个简单的辅助方法),这可能会更简单、更快。
        var hundred = new BigDecimal(100);
        var percentage = new BigDecimal(20);
        var value = new BigDecimal(500);
        
        var percentageFactor = 
            percentage.divide(hundred,2, BigDecimal.ROUND_HALF_UP);
        
        value = value.multiply(percentageFactor);
        System.out.println("final value:"+ value);