繁体   English   中英

位反转 N 位

[英]Bit reverse numbers by N bits

我试图找到一个简单的算法,将一个数字的位反转到 N 位。 例如:

对于 N = 2:

01 -> 10
11 -> 11

对于 N = 3:

001 -> 100
011 -> 110
101 -> 101

我一直在寻找的唯一事情是如何位反转一个完整字节,但这仅适用于 N = 8,而这并不总是我需要的。

有谁知道可以执行此按位运算的算法? 我需要为 FFT 做很多,所以我也在寻找可以非常优化的东西。

它是按位反向操作的 C# 实现:

public uint Reverse(uint a, int length)
{
    uint b = 0b_0;
    for (int i = 0; i < length; i++)
    {
        b = (b << 1) | (a & 0b_1);
        a = a >> 1;
    }
    return b;
}

上面的代码首先将 output 值向左移动,并将输入的最小 position 中的位添加到 output,然后将输入向右移动。 并重复它,直到所有位完成。 以下是一些示例:

uint a = 0b_1100;
uint b = Reverse(a, 4); //should be 0b_0011;

uint a = 0b_100;
uint b = Reverse(a, 3); //should be 0b_001;

此实现的时间复杂度为 O(N),其中 N 是输入的长度。

Dotnet fiddle中编辑

这是一个适合 (2<=N<=32) 的小型查找表解决方案。

对于 N==8,我想每个人都同意 256 字节数组查找表是通往 go 的方式。 同样,对于从 2 到 7 的 N,您可以创建 4、8、... 128 个查找字节 arrays。

对于 N==16,您可以翻转每个字节,然后重新排序这两个字节。 同样,对于 N==24,您可以翻转每个字节,然后重新排序(这会使中间的字节翻转但在相同的位置)。 应该很明显 N==32 将如何工作。

对于 N==9,将其视为三个 3 位数字(翻转每个数字,重新排序,然后进行一些屏蔽和移位以使它们处于正确的位置)。 对于 N==10,它是两个 5 位数字。 对于 N==11,中心位两侧的两个 5 位数字不会改变。 N==13 也是如此(两个 6 位数字围绕一个不变的中心位)。 对于像 N==23 这样的素数,它将是围绕中心 7 位数字的一对 8 位数字。

对于 24 到 32 之间的奇数,它变得更加复杂。 您可能需要考虑五个单独的数字。 考虑 N==29,这可能是围绕不变中心位的四个 7 位数字。 对于 N==31,它将是由一对 8 位数字和一对 7 位数字包围的中心位。

也就是说,这是一大堆复杂的逻辑。 这将是一个考验。 它可能比@MuhammadVakili 的位移解决方案更快(肯定适用于 N<=8),但可能不会。 我建议您使用他的解决方案 go。

使用字符串操作?

static void Main(string[] args)
{
    uint number = 269;
    int numBits = 4;
    string strBinary = Convert.ToString(number, 2).PadLeft(32, '0');
    Console.WriteLine($"{number}");
    Console.WriteLine($"{strBinary}");


    string strBitsReversed = new string(strBinary.Substring(strBinary.Length - numBits, numBits).ToCharArray().Reverse().ToArray());
    string strBinaryModified = strBinary.Substring(0, strBinary.Length - numBits) + strBitsReversed;
    uint numberModified = Convert.ToUInt32(strBinaryModified, 2);
    Console.WriteLine($"{strBinaryModified}");
    Console.WriteLine($"{numberModified}");

    Console.Write("Press Enter to Quit.");
    Console.ReadLine();
}

Output:

269
00000000000000000000000100001101
00000000000000000000000100001011
267
Press Enter to Quit.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM