Don't Understand What the Shifts Do


#1

This project was really straight-forward and easy to follow, but I still do not understand what some of the lines of code are doing. Can anyone explain what lines 9, and 14-20 are doing (they are labelled below)?

def rgb_hex():
  red = int(raw_input('Enter a RED value: '))
  # then determines if red is valid
  green = int(raw_input('Enter a GREEN value: '))
  # then determines if green is valid
  blue = int(raw_input('Enter a BLUE value: '))
  # then determines if blue is valid
  val = (red << 16) + (green << 8) + blue #line 9
  print '%s' % (hex(val)[2:].upper())

def hex_rgb():
  hex_val = raw_input('Enter a 6-digit HEX value: ')
  # determines if hex_val is valid
  hex_val = int(hex_val, 16) #line 14
  two_hex_digits = 2 ** 8  
  blue = hex_val % two_hex_digits
  hex_val = hex_val >> 8 
  green = hex_val % two_hex_digits 
  hex_val = hex_val >> 8 
  red = hex_val % two_hex_digits #line 20
  print '%s %s %s' % (red, green, blue)

I tried to figure out what line 9 does by inserting a way to visibly see what each shift does:

for x in range(0,17):
    print red << x
val = (red << 16) + (green << 8) + blue
print '%s' % (hex(val)[2:].upper())

It appears that every shift over multiplies the value of red by 2. This means that:
val = red * 2 ** 16 + green * 2 ** 8 + blue
What exactly is the point of this operation?

line 14: What does the second parameter in int() do?
lines 15-20: Why do we divide by 2 ** 8? What are the right shifts doing? Blue is not shifted; green is shifted 8; red is shifted 16 (which mirrors what happens in function rgb_hex(), so I assume that each shift indicates dividing by two this time around? Thanks for reading this long-winded post!


#2

Is it fair to ask us to explain someone else’s code?


#3

Well, I tried to problem solve and figure it out before coming to the forum. I already knew what RGB was coming in, and I at least read up on the hexadecimal system in the link that the lesson provided, so I understand the end results of hex_rgb() and the rgb_hex() functions completely. What I don’t get is what is going on when we use a shift on numbers other than base 2. Can you at least explain to me that concept in general? Even better, can you explain the purpose of doing so in the context of this code?


#4

Shift is a bitwise operation. So long as we shift the correct number of bits, any number base can be used.

>>> print (0xFF << 1)
510
>>> hex(510)
'0x1fe'
>>> bin(510)
'0b111111110'
>>> 

#5

Okay, I get it now. It was my understanding that bit-wise shifts would do the same thing in every base (ex: 10 << 1 != 100; It helps to see 10 as 0b1010 and the operation 0b1010 << 1 = 0b10100, because the shift is only ‘visible’ in binary.). Since the max value of RGB is 255, a number close to 256 (2^8), we shift 16 over for red and 8 over for blue because each color variable in binary actually takes up 8 spaces.
red = 0bxxxxxxxx
green = 0byyyyyyyy
blue = 0bzzzzzzzz
desired value looks like this in binary: 00000000 00000000 00000000
The shifts and addition make it look like this: 0b(xxxxxxxx yyyyyyyy zzzzzzzz)
Printing a slice of the val is purely cosmetic and to remove 0x from 0x(xx yy zz). Thanks mtf!


#6

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.