C分割位 [英] C Splitting bits

查看:25
本文介绍了C分割位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个16位地址,我需要将其拆分为15-8(用于页码)和7-0(用于偏移).

I have a 16 bit address and I need to split this into 15-8 for page number and 7-0 for offset.

那么,我想我可以对此进行按位运算吗?

So, I am guessing I could do bitwise ops on it?

假设 0xBEEF 是需要拆分的地址.

Let's say 0xBEEF is address that needs to be split.

页码:
0xBEEF&0xFF80 = 1011 1110 1110 1111&1111 1111 1000 0000 = 1011 1110 1000 0000 = 0xBE80

偏移:
0xBEEF&0x007F = 1011 1110 1110 1111&0000 0000 0111 1111 = 0000 0000 0110 1111 = 0x006F

除了C语言中针对宏的按位算术运算之外,还有其他方法可以做到这一点吗?

Are there different ways to do this besides bitwise arithmetic in C for macro?

推荐答案

是的,您可以通过几种方法进行不同的操作,但是我建议都不推荐.

Yes, there are a couple of ways you could do this differently, but I can recommend none of them.

在C语言中将16位值分为高位和低位是一件非常棘手的事情,因为位的顺序取决于硬件的字节顺序.如果您的系统是大字节序系统,则高位将被第二次存储;如果您的系统是小字节序,则高位将首先被存储.

splitting a 16 bit value in high and low bits is a very tricky thing to do in C, because the order of the bits depends on the endianness of your hardware. if your system is a big endian system, the high bit will be stored second, and if your system is little endian, the high bit is stored first.

让我们以0xBEEF为例,这是它在内存中的样子:

Let's take your example of 0xBEEF, here's what it looks like in memory:

little endian     |     big endian
-------------------------------------
... EF BE ...     |     ... BE EF ...

如果您使用位算术来分隔这两个字节,则不必关心它们在内存中的顺序,但是实际上任何其他方法都会受到影响,这要求您以某种方式检测字节序并有条件地编写程序便携式解决方案.

if you're using bit arithmetics to separate these two bytes, you don't have to care about their order in memory, but virtually any other method will be affected, requiring you to somehow detect the endianness and program conditionally to have a portable solution.

话虽如此,如果您不关心可移植性,可以使用以下两种替代方法:

That being said, here are a couple of alternatives that you could use if you don't care about portability:

1.)演员

该方法基本上是icepack提出的方法.您获取变量的地址,将其转换为指向 char 的指针,并将其视为数组,以获取单独的字节.

this method is basically the one proposed by icepack. you take the adress of the variable, cast it to a pointer to char, and treat it as an array, to get the separate bytes.

2.)联合

与演员表具有相同的效果,您还可以创建一个这样的联合:

having the same effect as the cast, you could also create a union like that:

union myvalue
  {
    uint16_t value;
    uint8_t bytes[2];
  }

能够分别处理字节和值

3.)相反

另一种完全不同的方法是首先将16位数据存储在无符号字符数组中,这是在地址上购买计算开销,但无需分隔字节.当然,如果该地址某种程度上是计算的结果,并且您仍然必须拆分字节,那么这将不再有意义.

another completely differently approach would be to store your 16 bit data in an array of unsigned chars in the first place, you're buying calculation overhead on the address, but you don't need to separate the bytes. of course, if the address is somehow the result of a calculation, and you have to split the bytes anyway, this would not make sense anymore.

最后一句话-如果您担心代码的可移植性,请使用AND并移位以提取字节.

这篇关于C分割位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆