aspose file tools*
The moose likes Associate Certification (OCAJP 7/8) and the fly likes Why does this Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Associate Certification (OCAJP 7/8)
Bookmark "Why does this " System.out.println(2 + 1.0f) " print 3.0?" Watch "Why does this " System.out.println(2 + 1.0f) " print 3.0?" New topic
Author

Why does this " System.out.println(2 + 1.0f) " print 3.0?

Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

Hi Ranchers!

I am a bit confused with this code snippet while I was studying:

System.out.println(2+1.0f) -> prints 3.0

Is the reason why it printed a float type is because float is larger than an int and so it got promoted to a float?
and same also as the double in the snippet below?

System.out.println(2+1.0d) -> prints 3.0
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5407
    
  13

I guess you expected "3"? Or maybe "21.0"?


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

Yap, that's right. I was expecting an int.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5407
    
  13

When executing calculations Java uses a "standard" datatype. When you are calculating with integers, the result of the calculation will be an int. That's why for example this code snippet won't compile (although you might think it would, it really doesn't ):


If you are doing some calculation with floating-points (decimals), the result will be a double. Again the reason why this won't compile too:


Also don't forget: when you use a floating-point literal value, it's automatically considered to be a double too. That's why you need to add an f (or F) when you need a float. So float f = 10.0; will not compile, but float f = 10.0F; does!

In your println-statement you are adding an int with a double, so the result will be a double (and thus 3.0 is printed)

Hope it helps!
Robert James Liguori
Author
Ranch Hand

Joined: Nov 27, 2007
Posts: 531
    
    5

Fantastic question, associated with "Binary Numeric Promotion"!

You will find the answer here:

The Java Language Specification, Java SE 8 Edition
http://docs.oracle.com/javase/specs/jls/se8/jls8.pdf (5.6.2 Binary Numeric Promotion)

"...If either operand is of type double , the other is converted to double ..."

-- Robert

Note: I also have this reference in the Java 8 Pocket Guide.


My Blog (I frequently post on Java, JSF and NetBeans)
Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

Roel De Nijs wrote:When executing calculations Java uses a "standard" datatype. When you are calculating with integers, the result of the calculation will be an int. That's why for example this code snippet won't compile (although you might think it would, it really doesn't ):


If you are doing some calculation with floating-points (decimals), the result will be a double. Again the reason why this won't compile too:


Also don't forget: when you use a floating-point literal value, it's automatically considered to be a double too. That's why you need to add an f (or F) when you need a float. So float f = 10.0; will not compile, but float f = 10.0F; does!

In your println-statement you are adding an int with a double, so the result will be a double (and thus 3.0 is printed)

Hope it helps!


Thanks! That's a very clear explanation, now I know why.
Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

Robert Liguori wrote:Fantastic question, associated with "Binary Numeric Promotion"!

You will find the answer here:

The Java Language Specification, Java SE 8 Edition
http://docs.oracle.com/javase/specs/jls/se8/jls8.pdf (5.6.2 Binary Numeric Promotion)

"...If either operand is of type double , the other is converted to double ..."

-- Robert

Note: I also have this reference in the Java 8 Pocket Guide.


Great! thank you for providing additional resource on that topic.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5407
    
  13

What do you think will happen with this code snippet? Compiles without error or compiler error (or something else)?

Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

Roel De Nijs wrote:What do you think will happen with this code snippet? Compiles without error or compiler error (or something else)?



I think that would compile with error, same reason as what you've said before.
It doesn't seem to make any difference making the two operands final.

But after I tried to compile it, there was no error. How did that happen?
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5407
    
  13

Ed Cardenas wrote:But after I tried to compile it, there was no error. How did that happen?

Yeah, it was a bit a trick question

The compiler is actually one smart cookie Because you used final for both variables, these are compile time constants. So the compiler knows the values of these variables and asks himself 1 question; does the value of the constant expression fit into the type of the variable? If it does, a narrowing primitive cast is used. If it doesn't, a compiler error is still given.

So for this example: the compiler knows there are 2 constants: 2 and 5, the value of the constant expression (2 + 5) is 7 and 7 fits the data type short, so compiler uses narrowing primitive cast (conversion) and no compiler error is given.

It's all explained in detail in JLS 5.2 Assignment Conversion:
In addition, if the expression is a constant expression (ยง15.28) of type byte, short, char, or int: - A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.


So if you now know all this extra info, what would happen with this code snippets?



Hope it helps!
Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

I get it now, thanks!

Roel De Nijs wrote:
So if you now know all this extra info, what would happen with this code snippets?



My guess was right, this will compile because the value of the constant expression is 127 and fits in a byte (-128 to 127) through narrow primitive casting.





Again my guess was right that this code snippet won't compile.
Because of the value of the constant expression is 128, it can't fit into a byte (-128 to 127) so there is compiler error.
Thanks for the great explanation!

I have a question again Roel, when I tried to remove one of the final keyword on the code snippet below, why was there a compiler error?
Isn't the expression promoted to a compile time constant?

Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5407
    
  13

Ed Cardenas wrote:Isn't the expression promoted to a compile time constant?


If you remove one of the final keywords, you don't have a compile time constant anymore and then we are back where we started: at the 1st post (and answer) of this thread
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5407
    
  13

And just for completeness: you can only have a compile time constant if you are using a literal value (like 200 or 10). So invoking a method and putting the result in a variable marked as final will NOT result in a compile time constant.

As the following code shows:
Ed Cardenas
Ranch Hand

Joined: Mar 29, 2014
Posts: 43
    
    1

Great! Many thanks for the explanation.
 
Don't get me started about those stupid light bulbs.
 
subject: Why does this " System.out.println(2 + 1.0f) " print 3.0?