I was trying to remove the fractional
part from a double
in case it is whole using:
(d % 1) == 0 ? d.intValue() : d
And encountered the following behavior which i don't understand:
public static void main(String[] args) { Double d = 5D; System.out.println((d % 1) == 0); // true System.out.println((d % 1) == 0 ? d.intValue() : "not whole"); // 5 System.out.println((d % 1) == 0 ? d.intValue() : d); // 5.0 }
As you can see on the third line, the operator chooses the else
value - 5.0
even though the condition (d % 1) == 0
is met.
What's going on here?
The conditional ternary operator can definitely be overused, and some find it quite unreadable. However, I find that it can be very clean in most situations that a boolean expression is expected, provided that its intent is clear.
The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.
There's a different emphasis: An if / else statement emphasises the branching first and what's to be done is secondary, while a ternary operator emphasises what's to be done over the selection of the values to do it with.
The Java ternary operator provides an abbreviated syntax to evaluate a true or false condition, and return a value based on the Boolean result.
The return type of the ternary conditional operator must be such that both the 2nd and 3rd operands can be assigned to it.
Therefore, in your second case, the return type of the operator is Object
(since both d.intValue()
and "not whole"
must be assignable to it) while in the third case it is Double
(since both d.intValue()
and d
must be assignable to it).
Printing an Object
whose runtime type is Integer
gives you 5
while printing a Double
gives you 5.0
.
The type of an expression a ? b : c
is always the same as c
or the closest common parent of b
and c
.
System.out.println((d % 1) == 0 ? d.intValue() : "not whole"); // Comparable a parent of Integer and String System.out.println((d % 1) == 0 ? d.intValue() : d); // Double is a widened int
BTW d % 1
will only check it is a whole not, not that it's small enough to fit in anint
value. A safer check is to see if the value is the same when cast to an int
or long
double d = 5.0; if ((long) d == d) System.out.println((long) d); else System.out.println(d);
or you can prevent it widening the long
back to a double with
double d = 5.0; System.out.println((long) d == d ? Long.toString((long) d) : Double.toString(d));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With