读书人

请问关于位移的有关问题

发布时间: 2012-08-13 13:21:53 作者: rapoo

请教关于位移的问题。
把一个无符号整形拆成若干个数据段。
用union可以解决,但是我想通过位移和宏的方式解决。
但是苦思之下,无良策,请各位帮忙。

我想把二进制的11写到一个无符号整形的二进制表示的第28位,长度为2,且不影响其他数据。
比如原来是11001100001,用宏WIRTE_UINT之后,就变成11001101101;
同样用READ_UINT之后,就可以从第28位读取指定长度的数据。

C/C++ code
#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;}



[解决办法]
感觉WRITE的定义还是不太清楚,比如,如果x的二进制为101,而len为2,结果应当怎样?如果x等于1结果又怎样?
[解决办法]
如果暂不考虑这些不明确的定义,大致思路是:把1左移len位,然后减1变成低len位全1的值,将这个值左移一定的位数,让全1部分对准要改写的位置,然后把它取反后与dest按位相与,就可以把dest的这些位清零,之后再把x移动一定的位数,按位或上去既可。READ所用的技巧也类似。
[解决办法]
WIRTE_UINT的思路:
C/C++ code
mask = ((1 << (len - 1)) - 1)des &= mask << pos           des |= x << pos
[解决办法]
探讨

可否稍微解释一下?
引用:

C/C++ code
#include <stdio.h>

#define WIRTE_UINT(des ,x ,pos ,len) ((des)&~(((1<<(len))-1)<<(32-(pos)-(len)))|((x)<<(32-(pos)-(len))))
#define READ_UINT(src ,……

[解决办法]
C/C++ code
#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 

读书人网 >C语言

热点推荐