Rounding a Bill Total in Java

This question already has an answer here:

  • Why not use Double or Float to represent currency? 14 answers

  • Seeing result.setText("Tip Amount : " + " $ " + Double.toString(tip_cal)); , I'm guessing you're getting a lot of nines in your output. Doubles can't store cents exactly, so the math will be off, but if you're not a financial institution and just dealing with < $10,000 transactions, do

    result.setText(String.format("Tip Amount :$%.2f", tip_cal));

    One more thing: decimalFormat.format(totalcost); is at best a no op, at worst a thread safety issue. It doesn't change the totalcost, it returns a StringBuffer (that shows you just how old it is).


    You really want to be using BigDecimal here, rather than Double. As @David mentioned, "Doubles can't store cents exactly". BigDecimal type can. BigDecimal gives you precise control over precision, and rounding.

    It's a much slower data type than Doubles, but for financial applications, it is far, far better.

    Granted, a simple tip calculator is not High Finance, but the basic tenet still applies. When operating on things such as dollar values, BigDecimal is a much better data type.


    Two things jump out at me....

    First Math.round can round DOWN, so a value of 5.22 would be rounded down to 6 , instead of up to 7

    Now you can use (int)totalcost + 1 which basically trims off the decimal elements or Math.ceil(totalcost) depending on your needs.

    The second is you don't seem to understand how formatter are using

    decimalFormat.format(totalcost);
    

    Won't do anything, numbers are free from formatting information. Instead, you use a formatter to return a representation of the value in the specified format...

    With all that tucked under our belts, something like...

    String tipFormat = decimalFormat.format((tip_cal)
    
    DecimalFormat decimalFormat = new DecimalFormat("$0.00");
    decimalFormat.setMinimumFractionDigits(2);
    
    try {
    
        double amount = Double.parseDouble("5.21");
        double tip_per = Double.parseDouble("20");
        double tip_cal = (amount * tip_per) / 100;
    
        double totalcost = amount + tip_cal;
    
        double rounded = (int)totalcost + 1;
    
        double roundtotal = rounded - totalcost;
    
        System.out.println("Tip Amount : " + decimalFormat.format((tip_cal)));
        System.out.println("Total Cost: " + decimalFormat.format(totalcost));
        System.out.println("Tip: " + decimalFormat.format(roundtotal) + " to round bill");
        System.out.println("Bill Tally: " + decimalFormat.format(totalcost + roundtotal));
    
    } catch (NumberFormatException e) {
        e.printStackTrace();
    }
    

    Will output...

    Tip Amount : $1.04
    Total Cost: $6.25
    Tip: $0.75 to round bill
    Bill Tally: $7.00
    

    Having said all that, double and float are not well suited for monetary calculations. You can use long or BigDecimal as alternatives, for example...

    NumberFormat nf = NumberFormat.getCurrencyInstance();
    
    try {
    
        BigDecimal amount = new BigDecimal(Double.parseDouble("5.21"));
        BigDecimal tip_per = new BigDecimal(Double.parseDouble("20"));
    
        BigDecimal tip_cal = amount.multiply(tip_per).divide(new BigDecimal(100));
        BigDecimal totalcost = amount.add(tip_cal);
    
        BigDecimal rounded = totalcost.setScale(0, RoundingMode.CEILING);
        BigDecimal roundtotal = rounded.subtract(totalcost);
    
        System.out.println("Tip Amount : " + nf.format((tip_cal)));
        System.out.println("Total Cost: " + nf.format(totalcost));
        System.out.println("Tip: " + nf.format(roundtotal) + " to round bill");
        System.out.println("Bill Tally: " + nf.format(totalcost.add(roundtotal)));
    
    } catch (NumberFormatException e) {
        e.printStackTrace();
    }
    

    This example uses the NumberFormat class instead of creating it's own formatter based on the DecimalFormat , not sure if this is available in Android or not, but you should consider using it (or the equivalent) as it takes into account the users local

    链接地址: http://www.djcxy.com/p/85818.html

    上一篇: 在乘法中使用双精度(java)

    下一篇: 以Java总计账单