Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • 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

Simple Question on variable assignment

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
short x = 0xBABE; // results in compilation error (decimal equivalent 47806 > Short.MAX_VALUE)
short x = 47806 ; // obvious compilation error number cannot fit into short variable
BUT
int x = 0xCAFEBABE ; // no compilation error even though decimal equivalent 3405 691 582 > Integer.MAX_VALUE)
int x = 3405691582; // obvious compilation error

Why there is no compilation error for int x = 0xCAFEBABE ?

 
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Remember that in Java the int data type is a 32-bit signed two's complement integer.
If you convert the hexidecimal value 0xCAFEBABE to its binary equivalent you'll get 11001010111111101011101010111110 (take my word for it).
The most significant bit here is the sign bit, which is 1, indicating that it should be treated as a negative number.
So when you convert this signed binary represention to its negated decimal equivalent (using binary arithmatic) you'll get a value of -889275714, which is within the range of the int datatype.
 
Shambhu Gupta
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Jelle for your response ..... understood your response regarding why the int assignment works.

However using the same analogy,
the assignment short x = 0xBABE should have also worked (but it does not)

Here also the sign bit is 1 and its value is -17408 which is in the range allowed for short (32767 to -32768)

So why does this not work ? I understand that in an assignment expression, the right hand value is always treated like an integer
 
Jelle Klap
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That has nothing to do with the fact that the value doesn't fit into a short, but because a hexadecimal literal is always treated as an int by default (or optionally as a long if you append an L to the literal), as you said. So the compiler will start to whine because you are attempting to assign a 32-bit value to a 16-bit datatype. If you explicitly cast the hexidecimal to the short datatype it will work:



By the way, this will be equivalent to the decimal value -17730, not -17408.
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I can see why the distinction between both cases might be a little confusing. Just think about the fact that integer literals in your code are always of type int (unless the suffix l or L is used, which makes the literal of type long.) That, and what Jelle said. When you assign an integer literal to a short, since the literal is actually of type int, there might be overflow if the value can't fit in the representation range of short. But when you are dealing with an int reference variable, there is no way that you can't fit an integer literal on it.
Also, notice that there are restrictions on int and long literals:
int x = 0XBABEBABE; // OK, 32 bits (4x8 bits)
int x = 0XBABEBABEB; // Compiler error (int number too large.)
long l = 0XBABEBABEBABEBABEl; // OK, 64 bits
long l = 0XBABEBABEBABEBABEBl // Compiler error (long number too large.)

As long as the int literal is legal, you can assign it to an int variable. But for smaller integral types, if a compile time check can determine that the value is too large and you are not casting to the smaller type, you will get a compiler error.
 
Shambhu Gupta
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Jelle and Ruben for your response,

Specifically with reference to Jelle's response, and going with the assumption that we are assiging an int literal to a short that is causing the compiler to whine, why does this work without the specific need to cast ?

short s = 0x7FFF; // no compile error, value is SHORT.MAX_VALUE

but this fails

short s = 0x8000; // value is SHORT.MIN_VALUE

Is this something to do with assigning a negative value to a short that is causing this error, since both these assignments are within the legal range of short ?


 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Shambhu, remember that integer literals are of type int. That means that 0X8000 is not a negative value. In reality it is the int value
0X00008000, which is a positive integer (Short.MAX_VALUE + 1.)
 
Shambhu Gupta
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jelle and Ruben:

Thanks !!! You guys are great and have cleared my doubts - in summary,

during an assignment like
short x = 0x7FFF, the compiler first checks to see if the number (always implicitly integer) can fit into the short variable, and if so, performs an implicit cast, so thats why this works since 0x7FFF is a valid number in the short range

for short x = 0xBABE, since 0xBABE is 47608 and is outside the range of a short, we need the explicit cast to short for the compiler to be happy.

Cheers,
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yup, you got it!

It's all in the JLS (5.2 Assignment Conversion):


[...] 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 represent-
able in the type of the variable.
[...]


Where they are referring to this statement:
variable = expression;

Remember that the expression must be a constant expression (compile-time constant.)

These would work fine:


But these would not work without an explicit cast:

 
reply
    Bookmark Topic Watch Topic
  • New Topic