Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make Java format a double like -3.2 rather than -3.1999999999999953?

Tags:

java

jscience

My app is producing doubles where Double.toString() produces "-3.1999999999999953" - whereas I would expect it to produce "-3.2".

I'm actually getting these doubles from JScience's Amount#getEstimatedValue().

I don't want to set an arbitrary number of digits for precision, since I don't know how many digits will be significant, but I don't want it to produce numbers that end in "99999999.*".

How can I convert Doubles to Strings without this problem?

like image 426
sanity Avatar asked Dec 15 '11 17:12

sanity


People also ask

How do you format a double in Java?

Just use %. 2f as the format specifier. This will make the Java printf format a double to two decimal places. /* Code example to print a double to two decimal places with Java printf */ System.

What is .2f in Java?

2f", value); The %. 2f syntax tells Java to return your variable (value) with 2 decimal places (. 2) in decimal representation of a floating-point number (f) from the start of the format specifier (%).

What does %D in Java do?

%d: Specifies Decimal integer. %c: Specifies character. %T or %t: Specifies Time and date. %n: Inserts newline character.


1 Answers

Recommended solution

BigDecimal.valueOf (hisDouble).toPlainString ()

The hack provided later in the last section of this post was the first thing that came to mind when trying to solve OPs question.

Then a friend asked what I was doing and said that OP be better of using BigDecimal and I went into facepalm mode..

But I'll leave the hack in this post so that the world can see how stupid I can be sometimes.


When printing you can use System.out.format.

The snippet below will will round the value of yourDecimal to one decimal and then print the value.

Double yourDouble = -3.1999999999999953;
System.out.format ("%.1f", yourDouble);

output

-3.2

The most stupid hack ever written

  public static String fixDecimal (Double d) {
    String  str = "" + d;
    int    nDot = str.indexOf ('.');

    if (nDot == -1)
      return str;

    for (int i = nDot, j=0, last ='?'; i < str.length (); ++i) {
      j = str.charAt (i) == last ? j+1 : 0;

      if (j > 3)
        return String.format ("%."+(i-nDot-j-1)+"f", d);

      last = str.charAt (i);
    }

    return str;
  }

...

Double[] testcases = {
  3.19999999999953,
  3.145963219488888,
  10.4511111112,
  100000.0
};

for (int i =0; i < testcases.length; ++i)
  System.out.println (
    fixDecimal (testcases[i]) + "\n"
  );

output

3.2
3.1459632195
10.45
100000.0
like image 70
Filip Roséen - refp Avatar answered Sep 28 '22 09:09

Filip Roséen - refp