Search code examples
cbit-manipulationbit-shiftbitwise-or

Why is my rgb to uint32 preprocessor macro giving me a wrong colorcode?


I am learning about bit wise operators and ran into this problem:

In computer graphics, colors are often stores as three numbers, representing red, green and blue intensities. Suppose that each number requires eight bits, and we'd like to store all three values in a single long integer.

Write a macro named MK_COLOR with three parameters (the red, green and blue intensities). MK_COLOR should return a long in which the last three bytes contain the red, green and blue intensities, with the red value as the last byte and the green value as the next-to-last byte.

The solution is:

#define MK_COLOR(r,g,b) ((long) (b) << 16 | (g) << 8 | (r))

I don't fully understand how the solution works, so I will try to break down my understanding, lets say r = 20 (10100), g = 30 (11110) and b = 40 (101000).

  1. b is shifted left by 16 bits so we get 00010100 00000000 00000000
  2. g is shifted by 8 bits so we get 11110000
  3. there is a | OR operator which looks like this:
  00010100 00000000 00000000 
| 11110000 00000000 00000000
 ---------------------------
  11110100 00000000 00000000 
  1. the last step does OR on this result we got but with r which looks like this:
  11110100 00000000 00000000 
| 10100000 00000000 00000000
 ---------------------------
  11110100 00000000 00000000 // result

The result is 11110100 00000000 00000000 which is 15990784 in decimal. This result however is incorrect according to when I run the program and get 2629140 as the answer.

Why is it wrong? Could you please explain what I did wrong and how I can better my understanding of this?


Solution

  • You have mistake in your shift results. Let's break it up:

    r = 20 = 0b00010100
    g = 30 = 0b00011110
    b = 40 = 0b00101000
    (long)(b) << 16 = 0b 00101000 00000000 00000000
    (long)(g) << 8  = 0b 00000000 00011110 00000000
    (long)(r)       = 0b 00000000 00000000 00010100
        -------------------------------------------
    Ored Result     = 0b 00101000 00011110 00010100 = 2629140