简体   繁体   English

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

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

I'm reading a datasheet and it says that the size of the image can be determined by this: 我正在阅读一个数据表,它说图像的大小可以通过以下方式确定:

Image Length = len 0 + Len 1 * 100h + Len 2 * 10000h 图像长度= len 0 + Len 1 * 100h + Len 2 * 10000h

And then the code implementing this on an mcu is 然后在MCU上实现此代码是

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

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

I was wondering if somebody could explain what is happening here? 我想知道是否有人可以解释这里发生了什么? How do you go from one to the other? 您如何从一个转到另一个? The mcu is 32-bit if that is relevant. 如果相关,则MCU为32位。

100h means 100 in hexadecimal notation which is 256 in decimal. 100h表示十六进制的100,十进制的256。

A multiplication of a number by 256 is equivalent of shifting its binary representation by 8 to the left. 将数字乘以256等于将其二进制表示形式向左移动8。

Or more generally: the multiplication of a number by 2^n is equivalent of shifting its binary representation by n to the left. 或更一般而言:将数字乘以2 ^ n相当于将其二进制表示形式向左移动n。 And a division of a number by 2^n is equivalent of shifting its binary representation by n to the right. 一个数字除以2 ^ n等效于将其二进制表示形式右移n个。

Example: 例:

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

So actually this: 所以实际上是这样的:

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

can be written as: 可以写成:

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

The 0x prefix means that the number is given in hexadecimal notation instead of decimal notation, so we can also write: 0x前缀表示该数字以十六进制表示法而不是十进制表示法,因此我们还可以编写:

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

Think of your L0 , L1 , and L2 as two-digit hexadecimal numbers XX , YY , and ZZ . 将您的L0L1L2视为两位十六进制数XXYYZZ

The situation here is that they're being put together to compose the six-digit hexadecimal number: 这里的情况是将它们组合在一起以组成六位数的十六进制数字:

0xZZYYXX

So one way of putting them together, using only bitwise operators, would be (L2 << 16) | (L1 << 8) | L0 因此,仅使用按位运算符将它们组合在一起的一种方法是(L2 << 16) | (L1 << 8) | L0 (L2 << 16) | (L1 << 8) | L0 (L2 << 16) | (L1 << 8) | L0 , which we can visualize like this: (L2 << 16) | (L1 << 8) | L0 ,我们可以像这样可视化:

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

But as Michael Walz has explained, shifting left by 1 bit is equivalent to multiplying by 2, and shifting left by 8 bits is equivalent to multiplying by 256, or 0x100. 但是正如迈克尔·沃尔兹(Michael Walz)解释的那样,向左移一位等于乘以2,向左移一位等于256乘以0x100。 Furthermore, bitwise OR is very close to addition, and as long as there's no overflow, bitwise OR pretty much is addition. 此外,按位或非常接近加法,并且只要没有溢出,按位或几乎就是加法。 So we get the same result as 所以我们得到的结果与

(L2 * 0x10000) + (L1 * 0x100) + L0

If you're still having trouble seeing this, think about base 10 instead of base 16. Suppose I wanted to "put together" the numbers 12, 34, and 56 to get 123456. I'd do that by writing 如果仍然有困难,请考虑以10为基数而不是以16为基数。假设我想将数字12、34和56“放在一起”以获得123456。我可以通过编写

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

Notice how the multipliers 10000 and 100 I used are eerily similar to 0x10000 and 0x100 in the hexadecimal example? 请注意,我使用的乘数10000和100与十六进制示例中的0x100000x100非常相似吗?

(Another way of thinking about these examples is that when you put L0 , L1 , and L2 together you were working with a three-digit number in base 256, and when I put 12, 34, and 56 together I was working in base 100. But if you're not ready to think about base 100 and base 256 yet, don't worry, you don't have to.) (考虑这些示例的另一种方式是,当您将L0L1L2放在一起时,您正在使用以256为底的三位数,而当我将12、34和56放在一起时,则是以100为底。但是,如果您尚未准备好考虑100和256的基数,请不用担心,您不必这样做。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM