如何使用 BigDecimal 显示始终保留 2 个小数点的数字?

问题描述 投票:0回答:7

我正在使用 BigDecimal 来获取一些价格值。要求是这样的,无论我们从数据库中获取什么值,显示的值都应该有 2 个小数点。

例如:

获取的值为 1 - 应显示为 1.00
获取的值为 1.7823 - 应显示为 1.78

我正在使用

setScale(2, BigDecimal.ROUND_HALF_UP)
但还有一些地方,如果来自 DB 的数据是一个整数,那么显示的也是一样的 !!

我的意思是,如果数据库中的值为 0,则它仅显示为 0。我希望它显示为 0.00

谢谢

java precision bigdecimal decimal-point
7个回答
67
投票

BigDecimal 是不可变的,对它的任何操作包括 setScale(2, BigDecimal.ROUND_HALF_UP) 都会产生一个新的 BigDecimal。正确的代码应该是

BigDecimal bd = new BigDecimal(1);
bd.setScale(2, BigDecimal.ROUND_HALF_UP); // this does change bd
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(bd);

输出

1.00

注意 - 由于 Java 9

BigDecimal.ROUND_HALF_UP
已被弃用,您现在应该使用
RoundingMode.ROUND_HALF_UP
.


14
投票

您可以使用汇总格式

BigDecimal bd = new BigDecimal(2.22222);
System.out.println(bd.setScale(2,BigDecimal.ROUND_UP));

希望这对你有帮助。


11
投票

要在 JAVA 中格式化数字,您可以使用:

 System.out.printf("%1$.2f", d);

其中 d 是您的变量或数字

 DecimalFormat f = new DecimalFormat("##.00");  // this will helps you to always keeps in two decimal places
 System.out.println(f.format(d)); 

2
投票

您需要使用像

NumberFormat
这样的东西和适当的语言环境来 format

NumberFormat.getCurrencyInstance().format(bigDecimal);

2
投票

BigDecimal.setScale 会工作。


0
投票

以下代码可能会有所帮助。

protected String getLocalizedBigDecimalValue(BigDecimal input, Locale locale) {
    final NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
    numberFormat.setGroupingUsed(true);
    numberFormat.setMaximumFractionDigits(2);
    numberFormat.setMinimumFractionDigits(2);
    return numberFormat.format(input);
}

0
投票

您可以以这种方式使用自定义注释: 自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FormatBigDecimal {
    String format() default "0.00";
}

然后您可以在字段上应用注释,并在构造函数中调用实现方法,如下所示:

public class TestClass {
   

    @FormatBigDecimal
    private BigDecimal myDecimal;
    public TestClass(BigDecimal myDecimal) throws ParseException, IllegalAccessException {
        this.myDecimal = myDecimal;
        formatBigDecimalFields();
    }

    public void setMyDecimal(BigDecimal myDecimal) {
        this.myDecimal = myDecimal;
    }

    public BigDecimal getMyDecimal() {
        return myDecimal;
    }
/**
In the above method, we are using reflection to get all the fields declared in the class of the object passed as an argument. Then, we are iterating over all the fields and checking whether the @FormatBigDecimal annotation is present on the field. If it is present, we are making the field accessible and getting its value.

We are also getting the format string from the @FormatBigDecimal annotation and using it to create a DecimalFormat object with the desired format. Then, we are formatting the value of the field using the DecimalFormat object and storing the formatted value in a string.

Finally, we are parsing the formatted value back into a BigDecimal object and setting it as the value of the field.
**/
    public void formatBigDecimalFields() throws IllegalAccessException, ParseException {
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(FormatBigDecimal.class)) {
                field.setAccessible(true);
                BigDecimal value = (BigDecimal) field.get(this);
                FormatBigDecimal formatAnnotation = field.getAnnotation(FormatBigDecimal.class);
                String formatString = formatAnnotation.format();
                NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
                DecimalFormat decimalFormat = (DecimalFormat) format;
                decimalFormat.applyPattern(formatString);
                String formattedValue = decimalFormat.format(value);
                BigDecimal formattedDecimal = new BigDecimal(formattedValue);
                field.set(this, formattedDecimal);
            }
        }
    }

}

使用方法:

 TestClass testClass = new TestClass(new BigDecimal("10000.899"));
        System.out.println(testClass.getMyDecimal());

会给出:

10000.90

© www.soinside.com 2019 - 2024. All rights reserved.