java - BigDecimal formatting -


i'd format bigdecimal in java 8 characters (including seperator), rounding half-up. examples:

12345.6789 -> "12345.68" 123        -> "   123.0" 0.12345678 -> "0.123457" 1.5        -> "     1.5" 0.0045     -> "  0.0045" 12         -> "    12.0" 

the result must have leading spaces fill 8 characters. what's easiest way?

i'm pretty sure not best way, it's 1 way.

first note if numbers have more 6 digits before period, or more more width - 2 digits before period, format .0 not work anymore.

string.format() uses half rounding method, can use first step output 8 characters.

bigdecimal b = new bigdecimal(0.0045); string format = "%8f"; string str = string.format(format, b); 

output:

12345.678900 123.000000 0.123457 1.500000 0.004500 12.000000 123456.000000 

by default string.format() uses precision of 6 bigdecimal. custom precision, need know how many digits before period , substract number (+ 1 period itself) total width.

width - digits - 1 

to number of digits can check if (number % radix) == number applies radix = 10, 100, 1000, ... fits know number of digits.

public static int digitsbeforeperiod(bigdecimal b) {     int number = b.intvalue();     int radix = 10;     int digits = 1;     while((number % radix) != number) {         radix *= 10;         ++digits;     }     return digits; } 

so next step modify format:

bigdecimal b = new bigdecimal(0.0045); int digits = digitsbeforeperiod(b); string format = "%8." + (8 - digits - 1) + "f"; string str = string.format(format, b); 

output:

12345.68 123.0000 0.123457 1.500000 0.004500 12.00000 123456.0 

still there lots of 0s, @ least rounding correct now. specify if number round integer, want print .0 suffix, otherwise without.

to achieve there might exist clever formats, didn't think further though. naive way simply:

while(str.endswith("0") && !str.endswith(".0")) {     str = str.substring(0, str.length()-1); } 

this removes last character of string until either doesn't end on 0 @ or ends .0.

now numbers have correct format, not aligned correctly:

12345.68 123.0 0.123457 1.5 0.0045 12.0 123456.0 

to align them, use string.format() again.

str = string.format("%" + width + "s", str); 

output:

12345.68    123.0 0.123457      1.5   0.0045     12.0 123456.0 

in context looks following. note included check wether or not number can formatted way - if not, print invalid. can of course print number, wanted show limitations of format.

public static string trimtowidth(bigdecimal b, int width) {     string str = "invalid";     int digits = digitsbeforeperiod(b);      // -2 period , 0     if(digits <= width - 2) {         // use width , (width - digits - 1) precision (-1 period)         string format = "%" + width + "." + (width - digits - 1) + "f";         // rounds half-up         str = string.format(format, b);          // trim trailing 0s, unless it's .0         while(str.endswith("0") && !str.endswith(".0")) {             str = str.substring(0, str.length()-1);         }     }      // add spaces in front     str = string.format("%" + width + "s", str);      return str; }  public static int digitsbeforeperiod(bigdecimal b) {     int number = b.intvalue();     int radix = 10;     int d = 1;     while((number % radix) != number) {         radix *= 10;         ++d;     }     return d; }  public static void main(string[] args) {     double[] values = new double[] {             12345.6789, 123, 0.12345678,             1.5, 0.0045, 12, 123456, 1234567     };      bigdecimal[] bigs = new bigdecimal[values.length];      for(int = 0; < bigs.length; ++i) {         bigs[i] = new bigdecimal(values[i]);         system.out.println(trimtowidth(bigs[i], 8));     }  } 

Comments

Popular posts from this blog

windows - Single EXE to Install Python Standalone Executable for Easy Distribution -

c# - Access objects in UserControl from MainWindow in WPF -

javascript - How to name a jQuery function to make a browser's back button work? -