Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - ternary operator weird behaviour

Tags:

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?

like image 339
Daniel Avatar asked Mar 27 '16 08:03

Daniel


People also ask

Is ternary operator bad practice Java?

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.

Can ternary operator have 3 conditions?

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.

Why ternary operator is better than if-else?

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.

Can ternary operator return True False?

The Java ternary operator provides an abbreviated syntax to evaluate a true or false condition, and return a value based on the Boolean result.


2 Answers

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.

like image 85
Eran Avatar answered Oct 07 '22 03:10

Eran


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)); 
like image 43
Peter Lawrey Avatar answered Oct 07 '22 02:10

Peter Lawrey