programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering OS Languages Paradigms IDEs Build Tools Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# RR #10

Thiru Narayanan
Greenhorn
Posts: 23
public class RR10
{
public static void main(String[] args)
{
byte a = 60;
byte b = (byte)~a;
System.out.println("a is " + a);
System.out.println("b is " + b);
}
}
In the topic with the same name (which is unforutnately locked) the reason for getting the value "b is -61" is given as b being an integer variable. But even if we cast the ~a to byte value, the answer is same. Is it because the '~' operator works only on integers? Even if so, after casting it should be only 8 bits long, is it not?

Jane Griscti
Ranch Hand
Posts: 3141
Hi Thiru,
That's my fault, sorry. The <code>~</code> works on any integer value: byte, short, int.
byte 60 = 0011 1100
When you invert it you get 1100 0011. Under two's-complement arithmetic, a '1' in the right most position indicates a negative number so the result, after inversion, is -61.
The same would happen with a short or int.
You can use the applet at http://www.javaranch.com/campfire/StoryBits.jsp to play with different bitwise operators and see their binary representations.
Hope that helps.
------------------
Jane Griscti
Sun Certified Programmer for the Javaï¿½ 2 Platform

Manfred Leonhardt
Ranch Hand
Posts: 1492
Hi Thiru,
You are correct in a sense. All java integral arithmetic results in an integer result. Lets step through what the compiler does:
b = ~a
1. Convert a from byte to integer:
a = 0000 0000 0000 0000 0000 0000 0011 1100
b = ~(0000 0000 0000 0000 0000 0000 0011 1100)
2. Flip all bits:
b = 1111 1111 1111 1111 1111 1111 1100 0011
At this point we have an integer variable being assigned to a byte variable. The compiler will complain about the sizing difference so you need to perform the cast (which you have done).
4. b = (byte)(1111 1111 1111 1111 1111 1111 1100 0011)
5. b = 1100 0011 = -61
Regards,
Manfred.

Thiru Narayanan
Greenhorn
Posts: 23
Thank you Jane & Manfred.
Can you please clarify my understanding one of the corollary from this solution.
"When you cast a primitive of higher capacity to a lower capacity then the sign may get changed"
for example, in the above case if:
byte a = -61;
byte b = (byte)~a;
Even though the right most (32nd bit) is 1 (i.e. negative), because of the casting the result will be positive (+60).
THIRU
Originally posted by Manfred Leonhardt:
b = ~a
1. Convert a from byte to integer:
a = 0000 0000 0000 0000 0000 0000 0011 1100
b = ~(0000 0000 0000 0000 0000 0000 0011 1100)
2. Flip all bits:
b = 1111 1111 1111 1111 1111 1111 1100 0011
At this point we have an integer variable being assigned to a byte variable. The compiler will complain about the sizing difference so you need to perform the cast (which you have done).
4. b = (byte)(1111 1111 1111 1111 1111 1111 1100 0011)
5. b = 1100 0011 = -61
Regards,
Manfred.

Jane Griscti
Ranch Hand
Posts: 3141
Hi Thiru,
'-61' is originally an <code>int</code>
1111 1111 1111 1111 1111 1111 1100 0011
which the compiler fits into a byte by chopping of the right-most bits, producing
1100 0011
In the next step, '~a', 'a' is promoted back to an <code>int</code> based on widening conversion rules, which extend the original sign
1111 1111 1111 1111 1111 1111 1100 0011
Then the inversion occurs
0000 0000 0000 0000 0000 0000 0011 1100
and the result is cast to a byte
0011 1100
The sign value is lost as a result of the inversion.
See JLS §5.6.1 Unary Numeric Promotion and JLS §5.1.2 Widening Primitive Conversion.
Hope that helps.
------------------
Jane Griscti
Sun Certified Programmer for the Javaï¿½ 2 Platform

Thiru Narayanan
Greenhorn
Posts: 23
Thank you very much Jane