3

I am trying to get a desired output based on a variable input. I can get close to what I want but there seems to be an issue with rounding a number.

What I want by example (input > output).

30 > 30
30.0 > 30
30.5 > 30,5
30.5555 > 30,6
30.04 > 30

The problem is that the last one comes back as 30.0. Now I understand why this is happening (because of the rounding up/down)

My code:

private String getDistanceString(double distance) {
        distance = 30.55;
        DecimalFormat df = new DecimalFormat(".#");
        if (distance == Math.floor(distance)) {
            //If value after the decimal point is 0 change the formatting
            df = new DecimalFormat("#");
        }
        return (df.format(distance) + " km").replace(".", ",");
    }
Rekijan Kileren
  • 183
  • 1
  • 3
  • 16

2 Answers2

2

It is almost always wrong to use == with floating point numbers. You should use Math.abs(a - b) < x.

private String getDistanceString(double distance) {
    DecimalFormat df = new DecimalFormat(".#");
    if (Math.abs(distance - Math.round(distance)) < 0.1d) {
        //If value after the decimal point is 0 change the formatting
        df = new DecimalFormat("#");
    }
    return (df.format(distance) + " km").replace(".", ",");
}

public void test() {
    double[] test = {30d, 30.0d, 30.5d, 30.5555d, 30.04d, 1d / 3d};
    for (double d : test) {
        System.out.println("getDistanceString(" + d + ") = " + getDistanceString(d));
    }
}
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • Thank you that fixed my problem, and indeed shame on me for using == – Rekijan Kileren Dec 14 '15 at 10:16
  • actually it's not a good way for float equal comparison. [Most effective way for float and double comparison](http://stackoverflow.com/q/17333/995714), [The Floating-Point Guide comparison](http://floating-point-gui.de/errors/comparison/) – phuclv Dec 14 '15 at 10:38
  • I just noticed that while it works with the examples I gave in my question it doesn't do what I want if the input is for example 30.99 which makes the output 31,0. Which should be 31. I tried adjusting the code a bit but came to the conclusion I do not understand it enough to do so. Could you help me further? – Rekijan Kileren Dec 14 '15 at 11:01
  • 1
    @RekijanKileren - Try using `Math.round` instead of `Math.floor`. – OldCurmudgeon Dec 14 '15 at 11:03
0

A hack around it, is to replace with regex

return 
       (""+df.format(distance))
       .replaceAll("\\.(0+$)?", ",") //replace . and trailing 0 with comma,
       .replaceAll(",$","") //if comma is last char, delete it
       + " km"; //and km to the string
nafas
  • 5,283
  • 3
  • 29
  • 57