Java用所有小数点设置双精度值,并且小数点后仅获得2位数字

时间:2018-09-28 09:13:32

标签: java hibernate decimal

在java中,我对存储和获得双​​重价值感到困惑。 目前,我正在创建包含一些会计部分的软件,我想存储与计算出的值相同的计算值,例如202.234234234212312,而在显示时,我希望将其显示为小数点后2位的202.23。 在计算中,我想用2,4或6位数字进行计算。

为此,我有2个选择

  1. 在计算值时存储值,在数量字段的getter方法中,我可以将其格式化。

    private Double amount;
    public Double getAmount() {
        DecimalFormat df2 = new DecimalFormat(".##");
        return Double.valueOf(df2.format(amount));
    }
    

但是此方法的问题是,只要我得到金额,它将一直获得格式化的数字。我无法获得实际的存储量。

  1. 我可以使用2个单独的字段进行获取和设置。

    private Double amount;
    private Double amountFormatted;
    
    public Double getAmount() {
        return amount;
    }
    
    public Double getAmountFormatted() {
        DecimalFormat df2 = new DecimalFormat(".##");
        return Double.valueOf(df2.format(amountFormatted));
    }
    

所以请提供更好的存储和获取十进制值的方法,谢谢。

3 个答案:

答案 0 :(得分:2)

首先,所有涉及金钱的计算均应使用BigDecimal进行,而不是两倍。双精度不能精确表示0.1之类的数量。

第二,如果您的getAmountFormatted仅用于输出,则不应返回Double而是String。

两种方法都使用相同的数量变量。

答案 1 :(得分:0)

如果我对您的理解正确,那么您只想为相同的值获取不同的格式,则只能有一个变量,而有2个获取字段,如下所示:

$ sudo setcap CAP_FOWNER+ep non_root_script
$ ./non_root_script
chmod: changing permissions of 'abc.txt': Operation not permitted

答案 2 :(得分:0)

提供格式化的数据进行显示不是实体的工作:将格式化留给实际进行显示的代码。更重要的是,这不是您的工作,因为实体类的程序员要:1)预期将来需要格式化的值,以及2)不断更新实体类以提供您需要的新格式化值没想到(不是,不能)。

因此,只需使用getAmount方法即可返回原始的纯净数据:

public class Entity {
    private BigDecimal amount;
    public BigDecimal getAmount(){ 
        return amount;
    }
    //...

}

,并从实体中消除getAmountFormatted。如果要显示格式化为两位小数的金额,只需使用getAmount()获取原始金额,然后立即将其格式化:

Entity e = ...;
DecimalFormat df = new DecimalFormat(".##");
System.out.println("The amount is " + df.format(e.getAmount());

这里有一个小故事,说明了为什么我认为这是要走的路...

假设您的实体中存在一个 second 金额otherAmount,该金额是在创建实体时包含的,因为有人认为可能需要 未来。并假设因为该字段当时没有计划使用,所以您不必费心创建getOtherAmountFormatted()方法来提供otherAmount的两位十进制格式。

现在,未来到来了。 otherAmount字段现在正在使用中,您需要使用原始的amount用两个小数位开始显示它。您知道您将不得不添加行

System.out.println("The other amount is " + ...

进入显示金额的代码。唯一的问题是,您如何完成那条线。您是否将getOtherAmountFormatted()方法添加到您的实体类,然后编写:

 System.out.println("The other amount is " + e.getOtherAmountFormatted());  // NO!!

还是您完全不接触实体类,而只写:

 System.out.println("The other amount is " + df.format(e.getOtherAmount()); // Yes!!

该实体不是最终需要otherAmount格式版本的类,因此它不必为了容纳现在恰好需要otherAmount格式版本的其他代码而进行更改。 {1}}。尤其是当另一段代码可以获取未格式化的数量时,未经修改的实体可以已经提供,然后为其进行所需的格式化。

下一个场景:在更进一步的将来,还会出现另一个要求来打印这些金额字段,但是现在需要 3 小数位。您是否要在实体类中添加更多方法以提供金额的三进制版本(除了已经提供了两位十进制版本的方法)?还是您完全不接触实体类而只是编写,此时您需要这些三进制十进制格式的值:

DecimalFormat df3 = new DecimalFormat(".###");
// ...
System.out.println("The amount in 3 decimals is " + df3.format(e.getAmount());
System.out.println("The other amount in 3 decimals is " + df3.format(e.getOtherAmount());