请教关于位移的问题。
把一个无符号整形拆成若干个数据段。
用union可以解决,但是我想通过位移和宏的方式解决。
但是苦思之下,无良策,请各位帮忙。
我想把二进制的11写到一个无符号整形的二进制表示的第28位,长度为2,且不影响其他数据。
比如原来是11001100001,用宏WIRTE_UINT之后,就变成11001101101;
同样用READ_UINT之后,就可以从第28位读取指定长度的数据。
#include <stdio.h>#define WIRTE_UINT(des ,x ,pos ,len) //怎么实现?#define READ_UINT(src ,pos ,len) //怎么实现?int main(){ unsigned int des = 1633; //原始:11001100001 des = WIRTE_UINT(des ,3 ,28 ,2); //目标:11001101101 unsigned int read = READ_UINT(des ,28 ,2); return 0;}
mask = ((1 << (len - 1)) - 1)des &= mask << pos des |= x << pos
[解决办法]
#include <stdio.h>#define WIRTE_UINT(des ,x ,pos ,len) ( \ (des) \ & \ ~( \ /* 除要修改的位为0,其余都为1 */ ( \ (1<<(len))-1 \ /* 长度为len位的1 */ ) \ <<(32-(pos)-(len)) \ /* 左移32-(pos)-(len)位 */ ) \ | \ ( \ (x) \ <<(32-(pos)-(len)) \ ) \)#define READ_UINT(src ,pos ,len) ( \ ( \ ( \ (unsigned)(src) \ ) \ >>(32-(pos)-(len)) \ /* 逻辑右移32-(pos)-(len)位 */ ) \ & \ ( \ (1<<(len))-1 \ /* 长度为len位的1 */ ) \)int main() // 1111111111222222222233{ //bit 01234567890123456789012345678901 unsigned int des = 0x661; // 00000000000000000000011001100001 des = WIRTE_UINT(des ,3 ,28 ,2); // 00000000000000000000011001101101 printf("des==0x%08X\n",des); unsigned int r = READ_UINT(des ,28 ,2); printf("r==%d\n",r); return 0;}//des==0x0000066D//r==3