Algorithm 不使用循环按位反转整数
我想写一个反整数位的程序。Algorithm 不使用循环按位反转整数,algorithm,Algorithm,我想写一个反整数位的程序。 Ex 11000101至10100011 我知道如何使用循环解决这个问题,但我遇到了使用字节移位的解决方案: num>>4|num<<4 num>>4 | num这不是反转位,而是交换nybles(4位单位)。换言之,它将转向: 1100 0101 (abcd efgh) 进入: 只有当数据类型实际上是8位(否则num>2)|((num&0x33)>1)|((num&0x55)1100 0101时,它才会这样做 >4表示我们正在将位右移4位
Ex 11000101至10100011
我知道如何使用循环解决这个问题,但我遇到了使用字节移位的解决方案:
num>>4|num<<4
num>>4 | num这不是反转位,而是交换nybles(4位单位)。换言之,它将转向:
1100 0101 (abcd efgh)
进入:
只有当数据类型实际上是8位(否则num>2)|((num&0x33)>1)|((num&0x55)1100 0101时,它才会这样做
>4
表示我们正在将位右移4位:
0000 1100
如前所述,它不是反转位,只是反转半字节。但您也可以将真正的位反转分解为类似的内容,例如(未测试):
//交换半字节
x=x>>4 | x>2)&0x33 |(x&0x33)>1)&0x55 |(x&0x55)如果您的整数在范围0..255
内,可以将所有256
反向值制成表格。(你可以把一小口列成表格,但这是穷人的解决办法。)
对于较大的值,使用该表交换并同时反转字节。您可以通过掩码和移位的组合,或者通过将四个字节映射到int来进行交换。一种用于反转整数中位顺序的递归方法——使用要反转的值和值的宽度调用
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
if WIDTH==1 then {
return VALUE;
} else {
// intermediate values may help make the algorithm more understandable
int HalfWidth = WIDTH >> 1; // number of bits to be swapped at this level
int HalfMask = HalfWidth-1; // mask for left or right half of the value
int RightHalfValue = VALUE & HalfMask; // extract right half from value
int LeftHalfValue = (VALUE >> HalfWidth) & HalfMask; // extract left half
// call reversing function on the two halves separately then swap the results
return (REVERSEBITS(RightHalfValue, HalfWidth) << HalfWidth)
| REVERSEBITS(LeftHalfValue, HalfWidth);
}
}
过程int反转息税前利润(int值;int宽度){
如果宽度==1,则{
返回值;
}否则{
//中间值可能有助于使算法更易于理解
int HalfWidth=WIDTH>>1;//在此级别要交换的位数
int HalfMask=HalfWidth-1;//值的左半部分或右半部分的掩码
int rightshalfvalue=VALUE&HalfMask;//从值中提取右半部分
int LeftHalfValue=(值>>HalfWidth)&HalfMask;//提取左半部分
//分别调用两半上的反转函数,然后交换结果
收益(反向息税前利润(右半值,半宽度)>1)-1),(宽度>>1))>1))
|反向息税前利润(((值>>(宽度>>1))和((宽度>>1)-1)),(宽度>>1));
}
}
通过更改函数定义,稍微简化函数代码,即使用要反转的值和值的一半宽度进行调用
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
if WIDTH==0 then {
return VALUE;
} else {
return (REVERSEBITS((VALUE & (WIDTH-1)), (WIDTH >> 1)) << WIDTH)
| REVERSEBITS(((VALUE >> WIDTH) & (WIDTH-1)), (WIDTH >> 1));
}
}
过程int反转息税前利润(int值;int宽度){
如果宽度==0,则{
返回值;
}否则{
收益(反向息税前利润((值和(宽度-1)),(宽度>>1))>宽度)和(宽度-1)),(宽度>>1));
}
}
您不了解哪一部分?在这里您可以找到人类已知的所有位反转方法:
((num & 0x01) << 7)
| ((num & 0x02) << 5)
| ((num & 0x04) << 3)
| ((num & 0x08) << 1)
| ((num & 0x10) >> 1)
| ((num & 0x20) >> 3)
| ((num & 0x40) >> 5)
| ((num & 0x80) >> 7)
num = ((num & 0xf0) >> 4) | ((num & 0x0f) << 4) // abcdefgh -> efghabcd
num = ((num & 0xcc) >> 2) | ((num & 0x33) << 2) // efghabcd -> ghefcdab
num = ((num & 0xaa) >> 1) | ((num & 0x55) << 1) // ghefcdab -> hgfedcba
0xf0, 0x0f -> 1111-0000, 0000-1111, shift by 4
0xcc, 0x33 -> 1100-1100, 0011-0011, shift by 2
0xaa, 0x55 -> 1010-1010, 0101-0101, shift by 1
(num&0xcc)>>2 (num&0x33)<<2
------------- -------------
abcdefgh abcdefgh
11001100 00110011 'and' with mask
-------- --------
ab00ef00 00cd00gh
00ab00ef cd00gh00 shift right/left
\ /
00ab00ef
cd00gh00 'or' them together
--------
cdabghef
ab cd ef gh
\ / \ /
X X
/ \ / \
cd ab gh ef
0000 1100
↓↓↓↓ ↓↓↓↓ |
0101 0000
---------
0101 1100
// swap nibbles
x = x >> 4 | x << 4;
// swap groups of 2
x = (x >> 2) & 0x33 | (x & 0x33) << 2;
// swap groups of 1
x = (x >> 1) & 0x55 | (x & 0x55) << 1;
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
if WIDTH==1 then {
return VALUE;
} else {
// intermediate values may help make the algorithm more understandable
int HalfWidth = WIDTH >> 1; // number of bits to be swapped at this level
int HalfMask = HalfWidth-1; // mask for left or right half of the value
int RightHalfValue = VALUE & HalfMask; // extract right half from value
int LeftHalfValue = (VALUE >> HalfWidth) & HalfMask; // extract left half
// call reversing function on the two halves separately then swap the results
return (REVERSEBITS(RightHalfValue, HalfWidth) << HalfWidth)
| REVERSEBITS(LeftHalfValue, HalfWidth);
}
}
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
if WIDTH==1 then {
return VALUE;
} else {
return (REVERSEBITS((VALUE & ((WIDTH>>1)-1)), (WIDTH>>1)) << (WIDTH>>1))
| REVERSEBITS(((VALUE >> (WIDTH>>1)) & ((WIDTH>>1)-1)), (WIDTH>>1));
}
}
procedure int REVERSEBITS( int VALUE; int WIDTH ) {
if WIDTH==0 then {
return VALUE;
} else {
return (REVERSEBITS((VALUE & (WIDTH-1)), (WIDTH >> 1)) << WIDTH)
| REVERSEBITS(((VALUE >> WIDTH) & (WIDTH-1)), (WIDTH >> 1));
}
}