10

I am stuck in the scenario below:

If x is 1.5 or lower then the final result will be x = 1. If x is large than 1.5 then x = 2.

The input number will be x/100.

For instance: input = 0.015 => x = 1.5 => display x = 1.

The problem I got is that float number is inaccurate. For example: input = 0.015 but actually it is something like 0.01500000000000002. In this case, x gonna be 1.500000000000002 which is large than 1.5 => display output is x = 2.

It happen so randomly which I don't know how to solve it. Like 0.5, 1.5 will give me the correct result. But 2.5, 3.5, 4.5, 5.5 will give me the wrong result. Then 6.5 will give me the correct result again.

The code I implemented is below:

float x = 0.015;
NumberFormat nf = DecimalFormat.getPercentInstance();
nf.setMaximumFractionDigits(0);
output = nf.format(x);

So depends on x, the output might be right or wrong. It is just so random.

I alos tried to use Math.round, Math.floor, Math.ceils but none of them seems work since float number is so unpredictable.

Any suggestion for the solution?

Thanks in advance.

Long Dao
  • 1,341
  • 4
  • 15
  • 33
  • Tell me: **How much** is `0.01500000000000002` different from `0.01500000000000000`? isn't it **negligible**? – Phantômaxx Aug 22 '16 at 11:49
  • have you tried DecimalFormatter to limit numbers after decimal to a fix value ? ...see this - http://stackoverflow.com/questions/8895337/how-do-i-limit-the-number-of-decimals-printed-for-a-double – Devansh Kumar Aug 22 '16 at 11:52
  • That's how it is. Float and double values behave that way since not all decimal fractions can be represented exactly. If you need to represent decimal fractions exactly (e.g. for monetary values) you can use BigDecimal (but calculations are much slower). – Henry Aug 22 '16 at 11:53
  • same as you round in java – Kaushal28 Aug 22 '16 at 12:01
  • hum seems confused. So if I use BigDecimal, will I get the exact value? The problem is that with the same input, iOS performs the correct results which Android only sometimes gives the correct results. – Long Dao Aug 22 '16 at 12:04
  • Can you add test case with expected output so that it is easier to check our answer? – Enzokie Aug 22 '16 at 12:34

4 Answers4

6

You could use String.format.

String s = String.format("%.2f", 1.2975118);
Linh
  • 57,942
  • 23
  • 262
  • 279
MurugananthamS
  • 2,395
  • 4
  • 20
  • 49
4

Here is my old code golf answer.

public class Main {

    public static void main(String[] args) {
        System.out.println(math(1.5f));
        System.out.println(math(1.500001f));
        System.out.println(math(1.49999f));
    }

    public static int math(float f) {
        int c = (int) ((f) + 0.5f);
        float n = f + 0.5f;
        return (n - c) % 2 == 0 ? (int) f : c;
    }

}

Output:

1
2
1
Enzokie
  • 7,365
  • 6
  • 33
  • 39
  • Hi there, seems like the outputs I need. Can you explain a bit about the math function that you wrote please? I am not fully understand. Thanks. – Long Dao Aug 22 '16 at 12:40
  • Which part sir? Also I can explain it through skype :) – Enzokie Aug 22 '16 at 12:41
  • I am confused about using int c and float n? – Long Dao Aug 22 '16 at 12:43
  • the `int c` serves as the cutted value while the `float n` holds the full value of the result. Since your goal is to round when the number is greater than lets say 1.5, I am just going to check if there is a remainder. I'm really sorry I suck at explaining :( – Enzokie Aug 22 '16 at 12:45
  • the 1.5 will have no remainder but 1.5002 will have. – Enzokie Aug 22 '16 at 12:50
  • Yeah I tested all the possible situations. This is the correct answer. Thanks a lot. :) – Long Dao Aug 22 '16 at 22:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/121577/discussion-between-enzokie-and-long-dao). – Enzokie Aug 23 '16 at 00:41
2

I like simple answers,

Math.round(1.6); // Output:- 2
Math.round(1.5); // Output:- 2
Math.round(1.4); // Output:- 1
0

I was facing the same problem, I used the DecimalFormat. This might help you.

float x = 1.500000000000002f;
DecimalFormat df = new DecimalFormat("###.######");
long l = df.format(x);
System.out.println("Value of l:"+l);
Archana
  • 597
  • 4
  • 18