C#反转整数的位

C#反转整数的位,c#,bit-manipulation,C#,Bit Manipulation,我知道在类似的方差中已经问过很多次了,但是我在C#(Unity3D)中的按位运算的输出方面遇到了问题 我正在尝试这样做,即获取整数(或无符号整数,任意一个)的位反转顺序,以便在中使用。所以如果我有0,1,2,3-我想以0,2,1,3结尾,如果我有0,1,2,3,4,5,6,7-我应该得到0,4,2,6,1,5,3,7 我尝试了一些在线的反转算法,比如: public uint ReverseBits(uint n) { n = (n >> 1) & 0x5555555

我知道在类似的方差中已经问过很多次了,但是我在C#(Unity3D)中的按位运算的输出方面遇到了问题

我正在尝试这样做,即获取整数(或无符号整数,任意一个)的位反转顺序,以便在中使用。所以如果我有0,1,2,3-我想以0,2,1,3结尾,如果我有0,1,2,3,4,5,6,7-我应该得到0,4,2,6,1,5,3,7

我尝试了一些在线的反转算法,比如:

public uint ReverseBits(uint n)
{
    n = (n >> 1) & 0x55555555 | (n << 1) & 0xaaaaaaaa;
    n = (n >> 2) & 0x33333333 | (n << 2) & 0xcccccccc;
    n = (n >> 4) & 0x0f0f0f0f | (n << 4) & 0xf0f0f0f0;
    n = (n >> 8) & 0x00ff00ff | (n << 8) & 0xff00ff00;
    n = (n >> 16) & 0x0000ffff | (n << 16) & 0xffff0000;
    return n;
}
我想尝试另一种算法,所以我找到了这个算法,正如前面指出的,它反转了字节:

public uint ReverseBytes(uint value)
{
    return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |
           (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;
}
公共uint反向字节(uint值)
{
返回值(value&0x000000FFU)8 |(value&0xFF000000U)>>24;
}

我得到了完全相同的数字,
x=2147483648
。像
>>
这样的按位运算符在C中执行与在其他语言(如C)中相同的功能,对吗?那么,我是否遗漏了一个步骤?

您当前使用的算法将整个整数中的位反转(即,对于
int
为32位,对于
long
为64位),而您真正想要的是只反转第一个
k
位(其中
n=2^k
用于位反转排列)

一个简单的解决方案是使用字符串:

int x = 6;
int k = 3;
// Binary representation of x of length k
string binaryString = Convert.ToString(x, 2).PadLeft(k, '0');
int reversed = Convert.ToInt32(Reverse(binaryString), 2);
其中:

或者,如果您不想使用字符串,您可以坚持使用按位运算符解决方案:

int x = 6;
int k = 3;
int reversed = 0;

for(int i = 0; i < k; i++) {
    // If the ith bit of x is toggled, toggle the ith bit from the right of reversed
    reversed |= (x & (1 << i)) != 0 ? 1 << (k - 1 - i) : 0;
}
intx=6;
int k=3;
int=0;
for(int i=0;i反转|=(x&(1i
)填充符号位。

您当前使用的算法在整个整数中反转位(即,int为32位,long为64位),而您真正想要的是只反转前
k
位(其中,
n=2^k
用于位反转置换)

一个简单的解决方案是使用字符串:

int x = 6;
int k = 3;
// Binary representation of x of length k
string binaryString = Convert.ToString(x, 2).PadLeft(k, '0');
int reversed = Convert.ToInt32(Reverse(binaryString), 2);
其中:

或者,如果您不想使用字符串,您可以坚持使用按位运算符解决方案:

int x = 6;
int k = 3;
int reversed = 0;

for(int i = 0; i < k; i++) {
    // If the ith bit of x is toggled, toggle the ith bit from the right of reversed
    reversed |= (x & (1 << i)) != 0 ? 1 << (k - 1 - i) : 0;
}
intx=6;
int k=3;
int=0;
for(int i=0;i反向|=(x&(1 i
)填充符号位。

如果您想要实现给定位长度的函数(如果您知道DFT具有给定长度,如64),则可以硬编码各种常量并编写针对该位长度定制的函数,例如:

public static int Reverse6Bits(int n)
{
    n = (n >> 1) & 0x55 | (n << 1) & 0xaa;
    n = (n >> 2) & 0x33 | (n << 2) & 0xcc;
    n = (n >> 6) & 0x03 | (n << 2) & 0x3c;
    return n;
}
公共静态int位(int n)
{

n=(n>>1)&0x55 |(n>2)&0x33 |(n>6)&0x03 |(n>(n如果您想要实现给定位长度的函数(如果您知道DFT具有给定的长度,例如64),那么您可以硬编码各种常量并根据该位长度编写函数,例如:

public static int Reverse6Bits(int n)
{
    n = (n >> 1) & 0x55 | (n << 1) & 0xaa;
    n = (n >> 2) & 0x33 | (n << 2) & 0xcc;
    n = (n >> 6) & 0x03 | (n << 2) & 0x3c;
    return n;
}
公共静态int位(int n)
{
n=(n>>1)&0x55(n>2)&0x33(n>6)&0x03(n>(n
uint-ret=n;
ret=ret>>16 | ret 8 |(ret&0x00ff00ff)>4 |(ret&0x0F0F0F)>2 |(ret&0x33333)>1 |(ret&0x555555)
uint ret=n;

ret=ret>>16 | ret 8 |(ret&0x00ff00ff)>4 |(ret&0x0F0F0F)>2 |(ret&0x33333333)>1 |(ret&0x555555)这些是不同的-第一个反转所有位,而第二个反转所有四个字节(4个8位块)
我得到了完全相同的数字,x=2147483648
-不,你没有。你输入
0x8000000
,输出是
0x00000080
-也就是说,字节被颠倒了(不是位)。@MatthewWatson当你说“不,你没有”你的意思是差异仅仅在于产生结果整数的方法,字节与位?因为有了这个代码,以及我在问题中列出的环境,我将结果打印到控制台,并且我确实得到了
2147483648
两次。@slanden我的意思是输入是0x8000000,输出是0x00000080,这不是2147483648(十进制)。为什么在您给出的示例数字中1的位反转为1?您将
0,1
变为
0,2
这些是不同的-第一个反转所有位,而第二个反转所有四个字节(4个8位块)
我得到了完全相同的数字,x=2147483648
-不,你没有。你输入
0x8000000
,输出是
0x00000080
-也就是说,字节被颠倒了(不是位)。@MatthewWatson当你说“不,你没有”你的意思是差异仅仅在于产生结果整数的方法,字节与位?因为有了这个代码,以及我在问题中列出的环境,我将结果打印到控制台,并且我确实得到了
2147483648
两次。@slanden我的意思是输入是0x8000000,输出是0x00000080,这不是2147483648(十进制)。为什么在您给出的示例数字中1的倒数位是1?您将
0,1
变成
0,2
,这是从您只有基于字符串的解决方案时开始的。@EvilTak您能更详细地解释您的答案吗?具体地说,1)什么是
k
,为什么我只想反转第一个
k
位?2)什么是
n
,为什么它等于2^k?3)是
x
应该反转的数字?1)和2)它们直接来自维基百科上的位反转排列的定义(在你的问题中链接)。在实现位反转排列之前,您没有试着理解它是什么吗?3)是的,
x
是要反转的数字。是的,我在发布此链接之前阅读了该链接。但我不太明白的是它在哪里显示(您也是这样做的)
n
是一个元素序列,
n=2^k
,它说是2的幂,但在文章中进一步说,
2^n
n
例如是0,1,2,3等,而不是所有这些都是2的幂
public static int Reverse3Bits(int n)
{
     return (0x73516240 >> (n << 2)) & 7;
}
    uint ret=n;
    ret = ret >> 16 | ret<<16;
    ret = (ret & 0xff00ff00) >> 8 | (ret & 0x00ff00ff) << 8;
    ret = (ret & 0xf0f0f0f0) >> 4 | (ret & 0x0f0f0f0f) << 4;
    ret = (ret & 0xcccccccc) >> 2 | (ret & 0x33333333) << 2;
    ret = (ret & 0xaaaaaaaa) >> 1 | (ret & 0x55555555) << 1;
    return ret;