为什么我的 rgb 到 uint32 预处理器宏给我一个错误的颜色代码?

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

我正在学习按位运算符和 运行 这个问题:

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.

解决方法是:

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

我不完全理解这个解决方案是如何工作的,所以我会尝试分解我的理解,比如说 r = 20 (10100)、g = 30 (11110) 和 b = 40 (101000).

  1. b 左移 16 位所以我们得到 00010100 00000000 00000000
  2. g 移动 8 位所以我们得到 11110000
  3. 有一个 | OR 运算符,如下所示:
  00010100 00000000 00000000 
| 11110000 00000000 00000000
 ---------------------------
  11110100 00000000 00000000 
  1. 最后一步对我们得到的结果进行 OR,但 r 看起来像这样:
  11110100 00000000 00000000 
| 10100000 00000000 00000000
 ---------------------------
  11110100 00000000 00000000 // result

结果为 11110100 00000000 00000000,十进制为 15990784。然而,根据我 运行 程序并得到 2629140 作为答案的时间,这个结果是不正确的。

为什么错了?您能否解释一下我做错了什么以及我如何才能更好地理解这一点?

你无意中加班了。

您开始于:

  • r = 00010100
  • g = 00011110
  • b = 00101000

然后:

  • b << 16 = 00101000 00000000 00000000
  • g << 8 = 00011110 00000000(你最初只向左移动了 3)

然后你将它们全部或在一起:

  00101000 00000000 00000000
  00000000 00011110 00000000
| 00000000 00000000 00010100
----------------------------
  00101000 00011110 00010100

你犯的错误是你在左边加了零,本质上是执行了一个额外的移位并改变了值。

您的轮班结果有误。让我们分解一下:

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