简体   繁体   English

使用C ++ constexpr对N位字进行位反转

[英]Bit reversal for N bit word using c++ constexpr

I am working on a bit reversal algorithm for an fft implementation, my implementation so far is 我正在为fft实现开发一个逆向算法,到目前为止我的实现是

//assume the proper includes

template<unsigned long bits>
unsigned long&& bitreverse(unsigned long value){
    std::bitset<bits> input(value);
    std::bitset<bits> result;
    unsigned long j=input.size()-1;
    for (unsigned long i=0; i<input.size(); ++i) {
        result[i]=input[j];
        j--;
    }
    return std::move(result.to_ulong());
}

I need to be able to reverse the bits in an N bit word. 我需要能够反转N位字中的位。 My current implementation is functional but I would like to re-write it so that the result can be used as a constexpr , the function signature would need to be either: 我当前的实现是功能性的,但是我想重写它,以便将结果用作constexpr ,函数签名必须是:

template<unsigned long bits>
constexpr unsigned long&& bitreverse(unsigned long value);

or: 要么:

template<unsigned long bits,unsigned long value>
constexpr unsigned long&& bitreverse();

or something close... 或接近...

I'm not sure how to begin implementing this. 我不确定如何开始执行此操作。

I would like to avoid bitwise operations if possible, but i'm not opposed to them. 如果可能的话,我想避免按位运算,但是我不反对它们。

Thanks 谢谢

You could just do this: 您可以这样做:

template <unsigned long bits>
constexpr unsigned long bitreverse(unsigned long value) {
    unsigned long result = 0;
    for (std::size_t i = 0, j = bits - 1; i < bits; ++i, --j) {
        result |= ((value & (1 << j)) >> j) << i;
    }
    return result;
}

I'm not sure why you want to use an r-value reference for the return type. 我不确定为什么要对返回类型使用r值引用。 It's not going to make anything more efficient, and I think will result in a dangling reference . 它不会使任何事情变得更有效率,我认为这将导致悬而未决的参考文献

Well, here's the obvious, "brute force" approach. 好吧,这是显而易见的“强力”方法。

This assumes that unsigned long long datatype on the implementation is a 64 bit integer. 假定实现上的unsigned long long数据类型是64位整数。 The code can be obviously pruned down for 32-bit platforms. 对于32位平台,显然可以删除该代码。

Observe that bitreverse can always be initially handled as a 64 bit bitreverse , then shifted right to get the correct number of bits out of it. 请注意, bitreverse最初始终可以被视为64位bitreverse ,然后向右移动以从中获得正确的位数。

This is a bit wordy, but it has the advantage that it's straightforward enough that most compilers can chew through a bitreverse of a constant at compile time. 这有点罗word,但它的优点是非常简单,大多数编译器可以在编译时bitreverse常量的bitreverse For a variable, this will certainly generate more code than the iterative approach, but modern CPUs will likely be able to plow through it without much delay, because they won't have to deal with looping and branch prediction. 对于一个变量,它肯定会比迭代方法生成更多的代码,但是现代CPU可能会在没有太多延迟的情况下进行遍历,因为它们不必处理循环和分支预测。

template<unsigned long bits>
constexpr unsigned long long bitreverse(unsigned long long v)
{
    return (((v & 0x00000001ULL) << 63) |
        ((v & 0x00000002ULL) << 61) |
        ((v & 0x00000004ULL) << 59) |
        ((v & 0x00000008ULL) << 57) |
        ((v & 0x00000010ULL) << 55) |
        ((v & 0x00000020ULL) << 53) |
        ((v & 0x00000040ULL) << 51) |
        ((v & 0x00000080ULL) << 49) |
        ((v & 0x00000100ULL) << 47) |
        ((v & 0x00000200ULL) << 45) |
        ((v & 0x00000400ULL) << 43) |
        ((v & 0x00000800ULL) << 41) |
        ((v & 0x00001000ULL) << 39) |
        ((v & 0x00002000ULL) << 37) |
        ((v & 0x00004000ULL) << 35) |
        ((v & 0x00008000ULL) << 33) |
        ((v & 0x00010000ULL) << 31) |
        ((v & 0x00020000ULL) << 29) |
        ((v & 0x00040000ULL) << 27) |
        ((v & 0x00080000ULL) << 25) |
        ((v & 0x00100000ULL) << 23) |
        ((v & 0x00200000ULL) << 21) |
        ((v & 0x00400000ULL) << 19) |
        ((v & 0x00800000ULL) << 17) |
        ((v & 0x01000000ULL) << 15) |
        ((v & 0x02000000ULL) << 13) |
        ((v & 0x04000000ULL) << 11) |
        ((v & 0x08000000ULL) << 9) |
        ((v & 0x10000000ULL) << 7) |
        ((v & 0x20000000ULL) << 5) |
        ((v & 0x40000000ULL) << 3) |
        ((v & 0x80000000ULL) << 1) |
        ((v & 0x100000000ULL) >> 1) |
        ((v & 0x200000000ULL) >> 3) |
        ((v & 0x400000000ULL) >> 5) |
        ((v & 0x800000000ULL) >> 7) |
        ((v & 0x1000000000ULL) >> 9) |
        ((v & 0x2000000000ULL) >> 11) |
        ((v & 0x4000000000ULL) >> 13) |
        ((v & 0x8000000000ULL) >> 15) |
        ((v & 0x10000000000ULL) >> 17) |
        ((v & 0x20000000000ULL) >> 19) |
        ((v & 0x40000000000ULL) >> 21) |
        ((v & 0x80000000000ULL) >> 23) |
        ((v & 0x100000000000ULL) >> 25) |
        ((v & 0x200000000000ULL) >> 27) |
        ((v & 0x400000000000ULL) >> 29) |
        ((v & 0x800000000000ULL) >> 31) |
        ((v & 0x1000000000000ULL) >> 33) |
        ((v & 0x2000000000000ULL) >> 35) |
        ((v & 0x4000000000000ULL) >> 37) |
        ((v & 0x8000000000000ULL) >> 39) |
        ((v & 0x10000000000000ULL) >> 41) |
        ((v & 0x20000000000000ULL) >> 43) |
        ((v & 0x40000000000000ULL) >> 45) |
        ((v & 0x80000000000000ULL) >> 47) |
        ((v & 0x100000000000000ULL) >> 49) |
        ((v & 0x200000000000000ULL) >> 51) |
        ((v & 0x400000000000000ULL) >> 53) |
        ((v & 0x800000000000000ULL) >> 55) |
        ((v & 0x1000000000000000ULL) >> 57) |
        ((v & 0x2000000000000000ULL) >> 59) |
        ((v & 0x4000000000000000ULL) >> 61) |
        ((v & 0x8000000000000000ULL) >> 63)) >> (64 - bits);
}

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

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