• 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

danchisholm Exam1 Operators Q29

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This question is from danchisholm:



it's asked for the output of that program which is 31,0

Explanation:


The expression (-1 & 0x1f) is equal to (0xffffffff & 0x1f), and both are equal to the hex value 0x1f or decimal 31. The expression (8 << -1) is equivalent to (8 << 0xffffffff). If the left hand operand of a shift expression is of type int, then the right hand operand is implicitly masked with the value 0x1f. In other words, the expression (8 << -1) is equivalent to (8 << (-1 & 0x1f)). By replacing -1 with the hexadecimal representation we have (8 << (0xffffffff & 0x1f)). By evaluating the right hand operand we have (8 << 31). When 8 is shifted 31 bits to the left, the result is zero since the only non-zero bit is lost as it is shifted beyond the most significant bit of the int data type.



My doubt:

What does it mean that when the left-hand operand is of type int the right-hand operand is implicity masked with 0x1f ? Is it because the right-hand operand is a negative number ? What would happend if the left-hand operand is of type long, then what ?

Please, somebody explain when this implicit mask is performed.

Thanks,
Francisco
 
Ranch Hand
Posts: 195
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
int has 32 bits, so you are allowed to shift a number of bits between 0 and 31. Only 5 bits are needed to described a number from 0 to 31, because 0 is

0000 0000 0000 0000 0000 0000 0000 0000

and 31 is

0000 0000 0000 0000 0000 0000 0001 1111

Only those 5 least-significant bits matter, so the compiler ignores the 27 most-significant bits. This behavior is equivalent to masking the number with & 0x1f

-1 in binary is

1111 1111 1111 1111 1111 1111 1111 1111

which is interpreted as 31 when only the 5 least-significant bits are taken into account. So (8 << -1) is the same as (8 << 31).

If you don't want to think in bit patterns, a simpler way of dealing with this situation is to remember this pattern:

(8 << 36) == (8 << 4)
(8 << 35) == (8 << 3)
(8 << 34) == (8 << 2)
(8 << 33) == (8 << 1)
(8 << 32) == (8 << 0)
(8 << 31) == (8 << -1)
(8 << 30) == (8 << -2)
(8 << 29) == (8 << -3)
(8 << 28) == (8 << -4)

Note that 36 % 32 is 4, and 32 % 32 is 0, but when you get to negative numbers, the modulus operator no longer applies. Instead, counting down from zero is the same as counting down from 32. So -1 is 31, -2 is 30, etc.

All this is based on the fact that int has 32 bits. When the left-hand operand is a long, remember that long has 64 bits. Instead of the 5 least-significant bits mattering, the 6 least-significant bits matter. You're allowed to shift a long variable a number of bits between 0 and 63. Instead of masking the right-hand operand by 0x1f (31) you mask it by 0x3f (63)
reply
    Bookmark Topic Watch Topic
  • New Topic