使用BigDecimal处理货币

mk1*_*k12 65 java currency bigdecimal

我试图使用longs为自己的货币制作自己的类,但显然我应该使用BigDecimal.有人可以帮助我开始吗?什么是用最好的方式BigDecimalS代表美元货币,比如至少使它但没有对仙超过2位小数,等等.对于API BigDecimal是巨大的,我不知道要使用哪些方法.此外,BigDecimal具有更好的精度,但如果它通过一个double?如果我做新的BigDecimal(24.99),它会如何与使用double?或者我应该使用使用的构造函数String

Vin*_*lds 74

以下是一些提示:

  1. 使用BigDecimal,如果你需要,它提供了(货币价值往往需要这个)的精度计算.
  2. 使用NumberFormat该类进行显示.本课程将处理不同货币金额的本地化问题.但是,它只会接受基元; 因此,如果您可以接受由于转换为a而导致的精确度的微小变化double,则可以使用此类.
  3. 使用NumberFormat该类时,请使用实例scale()上的方法BigDecimal来设置精度和舍入方法.

PS:如果你想知道,BigDecimal总是比double你必须用Java代表金钱价值更好.

PPS:

创建BigDecimal实例

这非常简单,因为BigDecimal它提供了构造函数来接受原始值String对象.您可以使用那些,最好是拍摄String物体的那些.例如,

BigDecimal modelVal = new BigDecimal("24.455");
BigDecimal displayVal = modelVal.setScale(2, RoundingMode.HALF_EVEN);
Run Code Online (Sandbox Code Playgroud)

显示BigDecimal实例

您可以使用setMinimumFractionDigitssetMaximumFractionDigits方法调用来限制显示的数据量.

NumberFormat usdCostFormat = NumberFormat.getCurrencyInstance(Locale.US);
usdCostFormat.setMinimumFractionDigits( 1 );
usdCostFormat.setMaximumFractionDigits( 2 );
System.out.println( usdCostFormat.format(displayVal.doubleValue()) );
Run Code Online (Sandbox Code Playgroud)

  • -1使用BigDecimal(double)构造函数..即使文档说这个构造函数是'不可预测的' (7认同)
  • 特别是在数字2上同意.保持视图(显示格式)与模型(BigDecimal)分开.您始终可以编写自定义的java.text.Format来处理特定的数据类型. (3认同)
  • 同意 更新了示例。 (2认同)

小智 35

我建议对Money Pattern进行一些研究.Martin Fowler在他的书"分析模式"中更详细地介绍了这一点.

public class Money {

    private static final Currency USD = Currency.getInstance("USD");
    private static final RoundingMode DEFAULT_ROUNDING = RoundingMode.HALF_EVEN;

    private final BigDecimal amount;
    private final Currency currency;   

    public static Money dollars(BigDecimal amount) {
        return new Money(amount, USD);
    }

    Money(BigDecimal amount, Currency currency) {
        this(amount, currency, DEFAULT_ROUNDING);
    }

    Money(BigDecimal amount, Currency currency, RoundingMode rounding) {
        this.currency = currency;      
        this.amount = amount.setScale(currency.getDefaultFractionDigits(), rounding);
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public Currency getCurrency() {
        return currency;
    }

    @Override
    public String toString() {
        return getCurrency().getSymbol() + " " + getAmount();
    }

    public String toString(Locale locale) {
        return getCurrency().getSymbol(locale) + " " + getAmount();
    }   
}
Run Code Online (Sandbox Code Playgroud)

来使用:

您将使用Money对象代表所有货币而不是BigDecimal.将钱表示为小十进制意味着您将在每个显示它的地方格式化钱.想象一下,如果显示标准发生变化.您必须在整个地方进行编辑.而是使用Money模式将钱的格式集中到一个位置.

Money price = Money.dollars(38.28);
System.out.println(price);
Run Code Online (Sandbox Code Playgroud)

  • 此问题的一个问题 - 并非所有货币都默认为金额之前的符号,或者中间有空格.这应该成为泡沫塑料的一部分. (4认同)

Vic*_*azi 8

或者,等待JSR-354.Java Money和Currency API即将推出!

  • 难道你不讨厌那些在不留任何评论的情况下检查好建议的人! (3认同)
  • #James Drinkard事实并非如此.JSR 354计划很快作为一个独立的库发布.最初的计划是等待Java 9,但临时库将很快发布 (2认同)
  • 也许是 Java 2035? (2认同)
  • 我能说什么,我已经不在那里了 (2认同)