• Post Reply Bookmark Topic Watch Topic
  • New Topic

Unary operators and byte short converted to int type  RSS feed

 
Patrick Cicero
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is my questions

The following fails to compile using the Unary ~ operator


So I am trying to understand all the JAVA rules on when byte or short are auto converted to an int type when
dealing with Unary operators





 
Knute Snortum
Sheriff
Posts: 4270
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's not that the unary operators are converting anything, it's that a literal "2" (or any number) is an int. (~) deals with bytes, so it has to know the type of the number. Since you didn't cast "2" to a byte, it will "not" the 2 as an int. This will cause a loss of precision.

I believe the reason you don't get a similar problem with (++) is because the compile can't be sure there is a problem, so it trusts you.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think we need a trip to the JLS (=Java® Language Specification) to see what it says about those operators.
The Bitwise Complement Operator (=one's complement) returns “the promoted type of the operand.” So a byte is promoted to an int.
The Prefix Increment Operator returns “the type of the variable.” So your byte remains a byte.
The same applies to the shorts later on.
 
Campbell Ritchie
Marshal
Posts: 56518
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your line 2 compiles because the right operand of the = operator is an int, but it is also a compile‑time constant (officially called a constant expression) which the compiler evaluates and finds is within the range of a byte. So an implicit cast is permissible. You will find the JLS calls this assignment converson.
 
Tim Holloway
Saloon Keeper
Posts: 18789
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:The Prefix Increment Operator[/url] returns “the type of the variable.” So your byte remains a byte.


This is actually trickier than that. The net effect of the prefix increment operator is what you'd get if you fetched a byte, converted it to an int, incremented it and then converted it back to a byte.

The "value" of the expression is therefore an int:



ALL of the following expressions are integer expressions, as they'll quickly demonstrate when you get to byte-unfriendly values. In the first case, the literal integer value 123 is narrowed to fit in "y", being effectively the same as "byte y = ((byte)123);" In all the other cases, the binary operands force widening under paragraph 5.6.2 of the spec. And again, this expression:



Is computed as an integer expression equivalent to this:


Allowing for mis-matched parentheses.

It is important to know this, because sometimes tricks are done that specifically take advantage of those rules. One common case is where the byte represents a character code. Another one would be in the case of polynomial byte expressions such as encryption algorithms.

It takes some careful reading of the spec and you have to realize that:

The type of the prefix increment expression is the type of the variable.


is NOT the same thing as the type of the VALUE of the prefix increment expression.

In cases like this my go-to text is Humpty-Dumpty in Alice Through the Looking-glass. Seriously.
 
Patrick Cicero
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for clearing this up.

I think the key is the JLS indicated
15.15.1. Prefix Increment Operator ++
The type of the prefix increment expression is the type of the variable

15.15.5. Bitwise Complement Operator ~
Unary numeric promotion (§5.6.1) is performed on the operand

Now here is a strange rule (sure to trip someone on a certification test)
15.15.3. Unary Plus Operator +
Unary numeric promotion (§5.6.1) is performed on the operand

so the following code



 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Patrick Cicero wrote:So I am trying to understand all the JAVA rules on when byte or short are auto converted to an int type when
dealing with Unary operators

I think Campbell's pretty much covered it, but my simple rule of thumb is:
Unless you've actually read the relevant JLS chapter, assume that ANY numeric expression that does not involve a long, float or double is an int.

It's not strictly correct (as he pointed out), but you rarely go wrong by the assumption.

And a numeric expression is anything that involves at least one numeric value and at least one operator.

You can think of it this way: if you're doing anything involving integers, Java WANTS to use ints.

HIH

Winston
 
Tim Holloway
Saloon Keeper
Posts: 18789
74
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston's Rule is pretty much accurate. The expression on line 3 of the preceding example is a graphic demonstration of how the type of the value of the expression isn't the same as the type of the expression. To prove it:



Should compile with nothing worse than a "potential data loss" warning, since you've told the compiler you're aware of what's going on.

The "promote-to-int" rule is actually a legacy of the C programming language, and one of the original reasons for it was that on most CPUs the generated machine code was often shorter and/or more efficient working internally with integers than code to actually do everything in terms of bytes.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!