移位操作,宏定义


工作中遇到的问题总结:
如何获取一个整数的某个字节的值,或bit的值,请用宏定义的方式实现:
#define GET_BIG_BYTE(X) (((X)>>24)&0xFF) //取得最高的一个字节数值,前提X为一个4字节的数。
总结,如果想获得某个字节的值,可用将字节低bit位全部移除,再用1来与上你要保留的bit,其他bit位用0来与。相信这个大家应该都知道,很简单。
如何实现对uint型的整数的某个bit赋值呢?如何用宏定义实现呢?
假设要设置uint的高16bit的低8bit的值为某个某个字节Y
#define SET_BYTE(X, Y) (X) =(X)&(~(0xF<<16))|((Y)<<16)
总结,如果想赋值则必须是两个值,X表示被赋值的数,Y表示要赋值的一个字节(当然也可以是uint型等但需要保证其他位被&成0)。
其次就是保证(X)=最终的结果,否则运算就白做啦。
之后就是你要将你要设置的位清楚为0。(X)&(~(0xF<<16)),记住一定是先取反再移位。
最后就是将要赋值的数移动到指定的位置就好啦,千万要记住其他位要被与成0啊。

彩蛋再最后啊!!!
前边的都挺简单的,只是想总结一个通用的编写规则,记住后能够快速编码而已。
那么最后的问题来了,如果是一个32bit的值左移32bit会是一个什么结果呢?
比如 uint a = 0xFF;
uint b = 0x0;
b = b| (a<<32);
答案是不确定,不同的编译器处理不同,如果a超过了32bit可能出现循环移位的情况。
最终结果就是 b = 0xFF 。我当前测试的结果就是这个啦。
也有一些处理器会出现a的bit位移除了,变成0.
所以要求我们编程时,对于一个32bit的变量不能移动超过32bit,即如果要对一个long long型的数值进行按位操作时,所对应的移动的值也应该是longlong型的。
如下:
#define SET_BYTE(X, Y) (X) =(X)&(~(0xF<<32))|((Y)<<32)
此时X一定是大于32bit的,要求Y也要是一个大于32bit的值进行移位。
最后再啰嗦一句哈,如果 Y是一个ushort型的,移位超过16bit会自动扩展到32bit。

你可能感兴趣的:(编译)