views:

709

answers:

4

Why does this code sometimes return 1E+1 whilst for other inputs (e.g. 17) the output is not printed in scientific notation?

BigDecimal bigDecimal = BigDecimal.valueOf(doubleValue).multiply(BigDecimal.valueOf(100d)).stripTrailingZeros();
System.out.println("value: " + bigDecimal);
+3  A: 

It's the implicit .toString() conversion that is happening when you pass the result into System.out.println().

Jordan S. Jones
+1 for pointing to the problem
dfa
+11  A: 

use bigDecimal.toPlainString():

 BigDecimal bigDecimal = BigDecimal.valueOf(100000.0)
                     .multiply(BigDecimal.valueOf(100d))
                     .stripTrailingZeros();
 System.out.println("plain      : " + bigDecimal.toPlainString());
 System.out.println("scientific : " + bigDecimal.toEngineeringString());

outputs:

plain      : 10000000
scientific : 10E+6
dfa
+1 for providing an actual solution instead of "here is the problem" like I did. :)
Jordan S. Jones
+3  A: 

The exact rationale for the behaviour of BigDecimal.toString() is explained in the API doc in great (and near incomprehensible) detail.

To get a consistent (and locale-sensitive) textual representation, you should use DecimalFormat.

Michael Borgwardt
+3  A: 

It's basically because you don't have enough significant digits. If you multiply something that only has 1 significant digit with 100, then you get something with only 1 significant digit. If it shows "10" then that basically says that it has 2 significant digits. The way to show it only has 1 significant digit is to show "1 x 10^1".

The following two decimals have the same value (10), but different "scales" (where they start counting significant digits; the top has 2 sig figs, the bottom has 1):

System.out.println(new BigDecimal(BigInteger.TEN, 0));  // prints 10
System.out.println(new BigDecimal(BigInteger.ONE, -1)); // prints 1E+1
newacct