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

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

提问人:programme3219873 提问时间:9/14/2021 最后编辑:Wör Du Schnaffzigprogramme3219873 更新时间:9/15/2021 访问量:146

问:

我正在学习位智运算符并遇到了这个问题:

在计算机图形学中,颜色通常存储为三个数字, 代表红色、绿色和蓝色强度。假设每个数字需要 8 位,我们希望将所有三个值存储在一个长整数中。

编写一个以三个参数(红色、绿色和蓝色强度)命名的宏。 应该返回一个 其中 最后三个字节包含红色、绿色和蓝色强度,红色值为最后一个字节,绿色值为倒数第二个字节。MK_COLORMK_COLORlong

解决方案是:

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

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

  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 00000000159907842629140

为什么是错的?你能解释一下我做错了什么,以及我如何才能更好地理解这一点吗?

C 操作 移 位

评论

1赞 user438383 9/14/2021
欢迎。请选择一个对有相同问题的其他人有用的标题。谢谢。
0赞 programme3219873 9/14/2021
有什么建议吗?
0赞 interjay 9/14/2021
你说“g 移动了 8 位,所以我们得到 11110000”,但这只移动了 3。后来你使用了“11110000 00000000 00000000”,它移动了 16。
0赞 programme3219873 9/14/2021
如果我的计算不正确,我深表歉意,这只是我的理解,因此我需要一些帮助来改善我的理解
0赞 klutt 9/14/2021
“g 移动了 8 位,所以我们得到 11110000”不,我们得到00011110 00000000

答:

1赞 dbush 9/14/2021 #1

你无意中做了一些额外的班次。

您从以下方面开始:

  • 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

你犯的错误是你在左边添加了零,实质上是执行了额外的移位并更改了值。

评论

0赞 programme3219873 9/15/2021
为什么你或他们完全?根据我的理解,b 和 g 不是先 OR'd 然后结果是 or 和 r 吗?
0赞 dbush 9/15/2021
@programme3219873 和 的移位值首先被 ORed 化。我把它们放在一起只是为了简化插图。bg
3赞 Roman Pavelka 9/14/2021 #2

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

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

评论

0赞 programme3219873 9/15/2021
为什么你或他们完全?根据我的理解,首先是 aret 和 OR'd,然后结果是 OR'd with ?bgr
0赞 Roman Pavelka 9/15/2021
这是一样的,最终结果是,如果在任何操作数中某个位置有一个,那么结果中就会有一个......