0

I recently ran in the following curiosity:

    double d=0.8608278036117554;
    String precision="float";

    float f=(float)d;
    String s="a " + (precision.equals("float") ? (float)d: d) + " Bonjour";
    String s2="a " + String.valueOf(precision.equals("float") ? (float)d: d) + " Bonjour";
    String s3="a " + (precision.equals("float") ? String.valueOf((float)d): String.valueOf(d)) + " Bonjour";


    println(d);
    println(f);
    println(s);
    println(s2);
    println(s3);


//0.8608278036117554
//0.8608278
//a 0.8608278036117554 Bonjour
//a 0.8608278036117554 Bonjour
//a 0.8608278 Bonjour

Why is it not possible to have a nice float when computing s or s2 ? Why is it still a double in case s and s2?

PS: This question has nothing to do with number formatting, in my opinion. I really want to understand why is the (float)d cast not working!!

Myoch
  • 793
  • 1
  • 6
  • 24
  • 1
    The result of a `boolean ? float : double` is a `double` It is casting to float but that is being cast back to a double. – Peter Lawrey Jun 21 '17 at 17:52

1 Answers1

3

Your expression precision.equals("float") ? (float)d: d has no effect, as the conditional operator has one single resulting type, which is double if one argument has the type float and the other has the type double.

So the first alternative will be widened from float to double and while the conversion from double to float and back to double may have an effect on the value, String.valueOf(double) will be called in either case.

You can use (precision.equals("float") ? String.valueOf((float)d): String.valueOf(d)) instead, whose method invocations are not redundant, as they are invocations of different methods, String.valueOf(float) and String.valueOf(double).

That said, you should not use narrowing to float to control the output. Check Format Float to n decimal places for alternatives which provide more control over the formatted output.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • I understand better now. But then if it's cast to a float and back to double, how come the precision is not lost? Shouldn't I have a bunch of zeros at the end instead of the real double decimals? – Myoch Jun 21 '17 at 17:58
  • 1
    The precision of `float` and `double` is defined in terms of *binary* digits, not decimal digits. For some values, this conversion may truncate some non-zero bits (that’s why I said, *may* have an effect on the value), but the resulting value isn’t necessarily a value with less decimal digits. – Holger Jun 21 '17 at 18:01
  • Indeed, I have tried the cast back and forth, separately from the whole "String" stuff, I get the same double from the float. So if I understand well, it is really a matter of coincidence that led back to the same double, and had I chosen another example, I could have spotted a change in the digits, right? – Myoch Jun 21 '17 at 19:02
  • Actually, it was no coincidence since I chose a value from the boggy file that was not correctly transformed to float values :s – Myoch Jun 21 '17 at 19:05
  • You may use `double d=0.1` for example. Both, `String.valueOf(d)` and `String.valueOf((float)d)` will produce `"0.1"`, but `String.valueOf((double)(float)d)` will produce `"0.10000000149011612"`. – Holger Jun 22 '17 at 07:11