通用循环位移行为
Generic circular bitwise shift behavior
这里有很多关于循环移位行为的问题;然而,即使在通过它们之后,我认为没有人提出以下声明,对此我有点困惑。
维基百科关于 Circular Shift 的声明:
/*
* Shift operations in C are only defined for shift values which are
* not negative and smaller than sizeof(value) * CHAR_BIT.
*/
unsigned int rotl(unsigned int value, int shift) {
return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift));
}
unsigned int rotr(unsigned int value, int shift) {
return (value >> shift) | (value << (sizeof(value) * CHAR_BIT - shift));
}
我对上面几行的解释是——在上面提到的两种情况下,换档行为是不确定的。
但是我看到了给出的例子
rotl(0x8000, -1)
答案为 0x00010000
.
rotl(8,-1)
答案为 16
.
处理此类移位参数(即负数和大于位数)的正确方法是什么?我是不是误解了什么?
#define CHAR_BITS ( 8 )
#define UINT_BITS ( sizeof(unsigned int) * CHAR_BITS )
// We need modulo, not remainder. This is a way to obtain it.
int mod(int x, int m) {
return ((x % m) + m) % m;
}
// Calculate left rotation for any shift value.
unsigned int rotl(unsigned int value, int shift) {
int lshift = mod(shift, UINT_BITS);
return (value << lshift) | (value >> (UINT_BITS - lshift));
}
这里有很多关于循环移位行为的问题;然而,即使在通过它们之后,我认为没有人提出以下声明,对此我有点困惑。
维基百科关于 Circular Shift 的声明:
/* * Shift operations in C are only defined for shift values which are * not negative and smaller than sizeof(value) * CHAR_BIT. */ unsigned int rotl(unsigned int value, int shift) { return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift)); } unsigned int rotr(unsigned int value, int shift) { return (value >> shift) | (value << (sizeof(value) * CHAR_BIT - shift)); }
我对上面几行的解释是——在上面提到的两种情况下,换档行为是不确定的。
但是我看到了给出的例子
rotl(0x8000, -1)
答案为 0x00010000
.
rotl(8,-1)
答案为 16
.
处理此类移位参数(即负数和大于位数)的正确方法是什么?我是不是误解了什么?
#define CHAR_BITS ( 8 )
#define UINT_BITS ( sizeof(unsigned int) * CHAR_BITS )
// We need modulo, not remainder. This is a way to obtain it.
int mod(int x, int m) {
return ((x % m) + m) % m;
}
// Calculate left rotation for any shift value.
unsigned int rotl(unsigned int value, int shift) {
int lshift = mod(shift, UINT_BITS);
return (value << lshift) | (value >> (UINT_BITS - lshift));
}