• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

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

 
Ranch Hand
Posts: 43
1
IntelliJ IDE Chrome Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I guess you expected "3"? Or maybe "21.0"?
 
Ed Cardenas
Ranch Hand
Posts: 43
1
IntelliJ IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yap, that's right. I was expecting an int.
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Author
Posts: 587
6
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ed Cardenas
Ranch Hand
Posts: 43
1
IntelliJ IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 43
1
IntelliJ IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What do you think will happen with this code snippet? Compiles without error or compiler error (or something else)?

 
Ed Cardenas
Ranch Hand
Posts: 43
1
IntelliJ IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 43
1
IntelliJ IDE Chrome Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 43
1
IntelliJ IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Great! Many thanks for the explanation.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic