0

I have a double d and want to make it into a double with a limited amount of decimals (l).

Which code is "better"?

double d = 81.2384;
double l1 = d - d % 0.1;
double l2 = (int) (d * 10) * 0.1;

I would also like to be able to use this to only allow half numbers (e.g. 9.5612 -> 9.5).

Konstantin Yovkov
  • 59,030
  • 8
  • 92
  • 140
Frithjof
  • 2,083
  • 1
  • 12
  • 37
  • check this http://stackoverflow.com/questions/17082115/set-double-format-with-2-decimal-places – Naren Mar 02 '14 at 14:06
  • 1
    If you're trying to output it with a limited number of digits, editing the value of the number itself is the wrong way to do it (and probably won't work anyway). Use a string formatting class like kocko suggested. – Tharwen Mar 02 '14 at 14:06
  • @Tharwen I am using this for reading values that should only be processed with a certain precision. – Frithjof Mar 02 '14 at 14:08
  • 1
    You **cannot** reliable round a binary floating point number (float/double in Java) to an exact number of decimal fractional digits. You can read about this in many questions and answers on SO, like here: http://stackoverflow.com/questions/1089018/why-cant-decimal-numbers-be-represented-exactly-in-binary (Why can't decimal numbers be represented exactly in binary?) – Erwin Bolwidt Mar 02 '14 at 14:10
  • @ErwinBolwidt That's true but you can reliable "round" a binary floating point number to the precision of halves, and that is what I want. – Frithjof Mar 02 '14 at 14:13
  • @Frithjof A double will always have the highest precision it can. If you round it to the nearest 2 decimal places, you're not reducing the precision - you're just changing the value. – Tharwen Mar 02 '14 at 14:15
  • @Frithjof As I read your question, you were asking about rounding to one decimal fractional digit. – Erwin Bolwidt Mar 02 '14 at 14:27

2 Answers2

2

Both solutions are acceptable. However, it is interested question, so I tried to compute proccesing time using this code :

    double d = 81.2384;
    double l1 = 0, l2 = 0;
    Long start = System.nanoTime();

    for (int i = 0; i < 1000 * 1000 * 100; i++) {
        l1 = d - d % 0.1;
    }
    Long time = System.nanoTime();
    Long l1speed = time - start;
    for (int i = 0; i < 1000 * 1000 * 100; i++) {
        l2 = (int) (d * 10) * 0.1;
    }
    Long l2speed = System.nanoTime() - time;

    System.out.println(l1 + l2); //to be sure that compiler does not ignore l1, l2
    System.out.println("computing l1 runs :" + ((double)l1speed / l2speed)+"faster than computing l2");

Which has this output :

computing l1 is: 76933.22854225677 times slower than computing l2
libik
  • 19,204
  • 9
  • 35
  • 72
  • 1
    Note that the second method will result in an integer overflow for any double value larger than 1/10th of the maximum integer value. – Tharwen Mar 02 '14 at 14:35
1

You can use a DecimalFormat:

double d = 81.2384;
DecimalFormat df = new DecimalFormat("#.##");
System.out.print(df.format(d));

which will print:

81.23
Konstantin Yovkov
  • 59,030
  • 8
  • 92
  • 140
  • Your code is helpful when printing numbers, but I want to read the numbers and process them only with a certain precision. `DecimalFormat.format()` returns a String. – Frithjof Mar 02 '14 at 14:10
  • And you can convert the returned `String` to a `double` with : `Double.valueOf(String s)` – Konstantin Yovkov Mar 02 '14 at 14:13
  • But what's the point of converting it into a String and back when you could just use a simple division? Also you aren't able to specify the precision of halves with DecimalFormat, right? – Frithjof Mar 02 '14 at 14:14