5

I have read this question Round a double to 2 decimal places It shows how to round number. What I want is just simple formatting, printing only two decimal places. What I have and what I tried:

double res = 24.695999999999998;
DecimalFormat df = new DecimalFormat("####0.00");
System.out.println("Value: " + df.format(res)); //prints 24.70 and I want 24.69
System.out.println("Total: " + String.format( "%.2f", res )); //prints 24.70

So when I have 24.695999999999998 I want to format it as 24.69

Community
  • 1
  • 1
sammy333
  • 1,384
  • 6
  • 21
  • 39
  • Looking for [Math.floor(double)](http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#floor%28double%29) perhaps? – OldCurmudgeon Apr 05 '15 at 22:04
  • 1
    If you're representing currency, as it appears you might be, could you not use `long` instead and represent the exact value (in pennies) rather than resort to a `double` and put up with the error margin caused by floating-point operations? – Bobulous Apr 05 '15 at 22:15

3 Answers3

8

You need to take the floor of the double value first - then format it.

Math.floor(double)

Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer.

So use something like:

double v = Math.floor(res * 100) / 100.0;

Other alternatives include using BigDecimal.

public void test() {
    double d = 0.29;
    System.out.println("d=" + d);
    System.out.println("floor(d*100)/100=" + Math.floor(d * 100) / 100);
    System.out.println("BigDecimal d=" + BigDecimal.valueOf(d).movePointRight(2).round(MathContext.UNLIMITED).movePointLeft(2));
}

prints

d=0.29
floor(d*100)/100=0.28
BigDecimal d=0.29
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • 1
    This may give unexpected results. For example, the closest double to 0.29 has exact value 0.289999999999999980015985556747182272374629974365234375, which truncates to 0.28. – Patricia Shanahan Apr 05 '15 at 23:12
7

Multiply the number by 100 and cast it to an integer. This cuts off all the decimal spaces except the two you want. Divide the result by 100.00. (24.69).

int temp = (int)(res * 100);
double result = temp / 100.00;

or the same thing in one line of code:

double result = ((int)(res * 100)) / 100.00;
David Lang
  • 71
  • 3
6

In addition to using Math.floor(double) and calculating a scale (e.g. * 100 and then / 100.0 for two decimal points) you could use BigDecimal, then you can invoke setScale(int, int) like

double res = 24.695999999999998;
BigDecimal bd = BigDecimal.valueOf(res);
bd = bd.setScale(2, RoundingMode.DOWN);
System.out.println("Value: " + bd);

Which will also give you (the requested)

Value: 24.69
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • 1
    Hey @Elliott Frisch this fails with 24.699999999999999 it converts it to 24.70 But even with one less "9" it converts correctly. Of course it's unlikely to have that many "9"s at the end but nevertheless just FYI. – Gunhan Dec 11 '17 at 14:13
  • Spent around 2 hours, finally found this and within minutes solved it, Thank you so much!! – Parag Pawar May 30 '19 at 07:52