This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes char to short  and vice versa Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "char to short  and vice versa" Watch "char to short  and vice versa" New topic
Author

char to short and vice versa

bobby chaurasia
Ranch Hand

Joined: Mar 30, 2002
Posts: 84
short s = 'A'; is acceptable
however
c = 'A';
s = c; is not, an explicit cast is required.
I understand you can not do a direct conversion from short to char and vice versa. But then why does it allow 'A' to be assigned to s?
and how do we explain this...
char c = Short.MAX_VALUE;
char c1 = Character.MAX_VALUE;
short s = (short)c;
short s1 = (short) c1;
System.out.println( "S is " + s);
System.out.println( "S1 is " + s1);
Gives
S is 32767
S1 is -1
Thanks
Jessica Sant
Sheriff

Joined: Oct 17, 2001
Posts: 4313

this thread covers a similar topic -- converting byte to int and the final modifier.
Lets look at your example:
short s = 'A'; is acceptable because the compiler knows without a doubt that the value of 'A' is within the range of a short -- so no problem it can make the assignment.
c = 'A'; Also acceptible -- not a problem
s = c; is not, an explicit cast is required. -- that's because the compiler can't be sure, at comiple-time, that the value in c can fit in a short without a possible loss of precision.
You know that c has the value of 'A' -- and that you haven't change the value to something bigger than 32767 (the largest value a short can hold). But the compiler can't be sure.
SO... it throws an error at compile-time forcing you to take responsibility for any possible loss of precision. By making that explicit cast you're telling the compiler that you know that everything will be ok -- and if there is a loss of precision -- that's your problem to deal with.
-----------
The 2nd half of your post is an excellent follow-up:

The JLS lists the range of the primitives
For short, from -32768 to 32767, inclusive
For char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535
You set c to the MAX_VALUE of short (32767)
and c1 to the MAX_VALUE of char (65535)
Then you try to store both of those in a short.
c can fit in a short no problem -- 32767 fits just fine.
c1 is too big for a short -- but in Java things just roll over -- if you go beyond the high value, it'll wrap down to the negative and keep going -- no overflow errors. So when you tried storing 65535 in a short -- it rolled over and ended up with a -1
That's why your output is 32767 and -1 respectively.
Does that help?
[ January 08, 2003: Message edited by: Jessica Sant ]

- Jess
Blog:KnitClimbJava | Twitter: jsant | Ravelry: wingedsheep
bobby chaurasia
Ranch Hand

Joined: Mar 30, 2002
Posts: 84
Yes it does.. Thanks a lot.
John Paverd
Ranch Hand

Joined: Nov 17, 2002
Posts: 115
short s = 'A'; is acceptable

The compiler knows that 'A' in Unicode is represented by the number 65, which is in the acceptable range for short variables.

c = 'A';
s = c; is not, an explicit cast is required.

Although you and I can see that the value stored in c is in the range that can be stored in a short variable, the compiler is not that smart, and assumes that c could for example contain \uffff, which cannot be stored in a short variable without an explicit cast. Remember that chars are unsigned, so \uffff represents 65535.
char c = Short.MAX_VALUE;
char c1 = Character.MAX_VALUE;
short s = (short)c;
short s1 = (short) c1;

c = (char)32767
c1 = '\uFFFF'
Since short and char are both 16 bits wide, Java can just copy the bits from the char variable to the short variable.
So s will also be 32767.
Since short is signed, and the first bit of s1 is 1, the number stored in s1 must be negative. See the recent posts that explain how to determine the magnitude of a negative number, given its hex representation.


SCJP 1.4
John Paverd
Ranch Hand

Joined: Nov 17, 2002
Posts: 115
oops - already been answered while i was typing a reply - must type faster
[ January 08, 2003: Message edited by: John Paverd ]
Jessica Sant
Sheriff

Joined: Oct 17, 2001
Posts: 4313

Originally posted by John Paverd:
oops - already been answered while i was typing a reply - must type faster

I hate when that happens -- but actually its a great thing (especially when both responses compliemnt the other)
bobby chaurasia
Ranch Hand

Joined: Mar 30, 2002
Posts: 84
Folks I really appreciate the quality input. Just extending the discussion a bit further:
char a = '\u0000';
1) a = 'B' - 'A' ; // compiles okay
2) a = 'A' - 'B' ; //fails during compilation
//gives possible loss of precision.
3) a = 'B' + 1 ; //compiles okay
4) a = 'B' - 1; // compiles okay
5) a = a++; //compiles okay
but
6) a = a + 1; // fails , possible loss of precision.
case 1 : compiler knows values of both the operands, both of them are promoted to integer, addition is performed. Since the difference is positive so it compiles okay.
case 2 : compiler knows values of both the operands but the difference is -ve and since char can not have negative values it fails.
case 6: How do we explain this >>>>
the compiler already knows the value of a, so adding 1 why does it require a explicit cast ?
[ January 09, 2003: Message edited by: bobby chaurasia ]
John Paverd
Ranch Hand

Joined: Nov 17, 2002
Posts: 115
Originally posted by bobby chaurasia:
Just extending the discussion a bit further:
6) a = a + 1; // fails , possible loss of precision.
case 6: How do we explain this >>>>
the compiler already knows the value of a, so adding 1 why does it require a explicit cast ?

Bobby
The result of a + 1 is an int, so it must be cast to char before assignment to a char variable.
The compiler will only do implicit narrowing from int to char if it can verify that the results of an int expression are in char's range (0 - 65535). Since a is not a constant, the compiler cannot be sure that a has any specific value. a could contain \uffff for all the compiler knows. The compiler does not execute the program as it compiles it, so it doesn't know that the value in a will allow a = a + 1 to be executed without a cast.
[ January 09, 2003: Message edited by: John Paverd ]
Karin Paola Illuminate
Ranch Hand

Joined: Oct 18, 2002
Posts: 109
Jessica / John,
You state:
c1 is too big for a short -- but in Java things just roll over -- if you go beyond the high value, it'll wrap down to the negative and keep going -- no overflow errors. So when you tried storing 65535 in a short -- it rolled over and ended up with a -1

and
Since short is signed, and the first bit of s1 is 1, the number stored in s1 must be negative. See the recent posts that explain how to determine the magnitude of a negative number, given its hex representation.

Where can I find more information about "roll over"?


I not only use all the brains that I have, but all that I can borrow. [Laurence J. Peter]
John Paverd
Ranch Hand

Joined: Nov 17, 2002
Posts: 115
Karin
The roll over is a consequence of the 2s complement format that Java uses to store byte, short, int, and long.
Please refer to http://www.cs.man.ac.uk/Study_subweb/Ugrad/coursenotes/cs1031/Lec05-2sComp.pdf
It has a diagram titled "2's complement wheel" that visually shows why adding 1 to the MAX_VALUE will yield MIN_VALUE.
Karin Paola Illuminate
Ranch Hand

Joined: Oct 18, 2002
Posts: 109
Thanks for the wheel, John.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: char to short and vice versa
 
Similar Threads
characters and numbers seperation in a string
prog of multiple inputs
Implicit Narrowing and Casting
Casting
Clrify results from SCJP mock exam site