解释数据表中的十六进制并使用 C 按位​​左移运算符进行转换

Interpreting hex in a datasheet and converting using C bitwise left shift operators

我正在阅读数据表,它说图像的大小可以通过以下方式确定:

Image Length = len 0 + Len 1 * 100h + Len 2 * 10000h

然后在单片机上实现的代码是

L0 = Buffer[5];
L1 = Buffer[6];
L2 = Buffer[7];

image_size = L0 + (L1 << 8) + (L2 << 16);

我想知道是否有人可以解释这里发生了什么?你如何从一个转到另一个?如果相关的话,单片机是 32 位的。

100h表示十六进制为100,十进制为256。

一个数乘以 256 相当于将其二进制表示向左移动 8。

或者更一般地说:一个数乘以 2^n 相当于将其二进制表示向左移动 n。一个数除以 2^n 相当于将它的二进制表示向右移动 n。

示例:

        2  * 256 = 512
000000010 <<   8 = 100000000    // << is the shift left operator

实际上是这样的:

image_size = L0 + (L1 << 8) + (L2 << 16);

可以写成:

image_size = L0 + (L1 * 0x100) + (L2 * 0x10000);

0x前缀的意思是这个数是用十六进制而不是十进制给出的,所以我们也可以这样写:

image_size = L0 + (L1 * 256) + (L2 * 65536);

将您的 L0L1L2 视为两位十六进制数 XXYYZZ .

这里的情况是把它们放在一起组成六位十六进制数:

0xZZYYXX

因此,仅使用按位运算符将它们放在一起的一种方法是 (L2 << 16) | (L1 << 8) | L0,我们可以这样想象:

L0    ZZ         =    000000XX
L1    YY << 8    =    0000YY00
L2    ZZ << 16   =    00ZZ0000
                      --------
       bitwise OR:  0x00ZZYYXX

但正如 Michael Walz 所解释的那样,左移 1 位相当于乘以 2,左移 8 位相当于乘以 256,即 0x100。此外,按位或与加法非常接近,只要不溢出,按位或几乎就是加法。所以我们得到与

相同的结果
(L2 * 0x10000) + (L1 * 0x100) + L0

如果您仍然看不懂,请考虑以 10 为基数而不是以 16 为基数。假设我想 "put together" 数字 12、34 和 56 得到 123456。我会这样做通过写作

(12 * 10000) + (34 * 100) + 56

注意我使用的乘数 10000 和 100 与十六进制示例中的 0x100000x100 有何惊人的相似?

(考虑这些示例的另一种方式是,当您将 L0L1L2 放在一起时,您使用的是以 256 为基数的三位数,当我将 12、34 和 56 放在一起时,我正在以 100 为基数工作。但是如果你还没有准备好考虑以 100 为基数和以 256 为基数,别担心,你不必考虑。)