开发者

Trim More than two trailing Zeros in BigDecimal

开发者 https://www.devze.com 2023-03-09 12:11 出处:网络
What would be a good way to trim more than two trailing zeros for a BigDecimal So 1.2200 would print 1.22 and 1.0000 would print 1.00

What would be a good way to trim more than two trailing zeros for a BigDecimal

So 1.2200 would print 1.22 and 1.0000 would print 1.00

Edit As well as to return 1.222200 as 1.2222 and 1.220000001 as 1.220000001 etc. So disregarding first two zeros I want to trim any incoming 0s and not trim non-zero values

One way could be to multiply, then apply the built in tri开发者_如何学Pythonm trailing zeros and then divide by 100. It could be problematic with corner cases but the values in my problem are currency based and would never exceed the bounds set by Java (or else it means my software is dealing with bids which are in gazzilions of dollars)

The ugly solution is as folows

System.out.println(((new BigDecimal("1.230223000")
                                 .multiply(new BigDecimal("100.0"))
                                 .stripTrailingZeros()).divide(new BigDecimal("100.0"))));


Update: Having those mixed requirements (i.e. at least 2 digits after the decimal point should be displayed, but as many as necessary) is not trivially implemented, but you can come close:

Combine stripTrailingZeros() with DecimalFormat to get the desired behaviour (or close to it):

DecimalFormat df = new DecimalFormat("0.00########")
String formatted = df.format(bigDecimal.stripTrailingZeros())

This will format any BigDecimal value with at least 2 digits after the decimal point and up to 10 digits after the decimal point, if it improves the precision.

BigDecimal values with more than 10 digits after the decimal point will still be cut off:

      input      |  output
-----------------+----------
 1.20000         | 1.20
 1.23000         | 1.23
 1.2301          | 1.2301
 1.230001000     | 1.230001
 1.2300000000001 | 1.23

Original answer:

If you always want to have exactly 2 digits after the comma and know that you won't lose precision this way, then you can call setScale(2, RoundingMode.UNNECESSARY):

System.out.println(new BigDecimal("1.23000").setScale(2, RoundingMode.UNNECESSARY));

This code will print 1.23. Note that this will throw an ArithmeticException when rounding would be necessary (i.e. anything after the first 2 digits is not zero).

If your values can have a higher precision and you want to apply some rounding, simply replace RoundingMode.UNNECESSARY with the appropriate value:

System.out.println(new BigDecimal("1.2301").setScale(2, RoundingMode.CEILING));

This will print 1.24.

If you don't know the exact number of digits but want as few as possible (i.e. you want the smallest possible scale for your BigDecimal) then calling stripTrailingZeros() will do exactly what you want:

System.out.println(new BigDecimal("1.230001000").stripTrailingZeros();

This will print 1.230001.


Check this,

import java.text.DecimalFormat;
import java.text.NumberFormat;

public class DecimalFormatExample
{
  public static void main(String args[])
  {
  double amount = 2192.015;
  NumberFormat formatter = new DecimalFormat("#0.00");
  System.out.println("The Decimal Value is:"+formatter.format(amount));
  }
}  


This method will give you the result you want (monetary round): (what is String because it's better for BigDecimal see documentation)

public static float roundUp(String what, int howmuch) throws Exception{

    try {
        return (new BigDecimal(what).setScale(howmuch, BigDecimal.ROUND_UP)).floatValue();
    } catch (NumberFormatException nfe) {
        throw new Exception("BigDecimal cannot parse value : " + what, nfe);
    }
}


If it's for displaying purposes use:

BigDecimal d = new BigDecimal("1.2200");
NumberFormat n = NumberFormat.getCurrencyInstance(Locale.US);
String s = n.format(d.doubleValue());


For outputting as String, use DecimalFormat.

Otherwise, use this:

public static BigDecimal stripToMinimumScale(BigDecimal value, 
                                             final int minimumScale) {
  if (value.scale() == minimumScale) // Already correct scale
    return value;
  else {
    value = value.stripTrailingZeros();
    return (value.scale() < minimumScale) ?  
        value.setScale(minimumScale) : // Too few decimals, needs zero pad
        value; // Do not round any significant digits
  }
}


BigDecimal d = new BigDecimal("59.0000");
String d1 = new DecimalFormat().format(d);
System.out.println("d1 is " + d1);
0

精彩评论

暂无评论...
验证码 换一张
取 消