Best practices for circular shift (rotate) operations in C++

前端 未结 16 1559
情深已故
情深已故 2020-11-22 00:09

Left and right shift operators (<< and >>) are already available in C++. However, I couldn\'t find out how I could perform circular shift or rotate operations.

16条回答
  •  天涯浪人
    2020-11-22 00:50

    C++20 std::rotl and std::rotr

    It has arrived! http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html and should add it to the header.

    cppreference says that the usage will be like:

    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
        std::uint8_t i = 0b00011101;
        std::cout << "i          = " << std::bitset<8>(i) << '\n';
        std::cout << "rotl(i,0)  = " << std::bitset<8>(std::rotl(i,0)) << '\n';
        std::cout << "rotl(i,1)  = " << std::bitset<8>(std::rotl(i,1)) << '\n';
        std::cout << "rotl(i,4)  = " << std::bitset<8>(std::rotl(i,4)) << '\n';
        std::cout << "rotl(i,9)  = " << std::bitset<8>(std::rotl(i,9)) << '\n';
        std::cout << "rotl(i,-1) = " << std::bitset<8>(std::rotl(i,-1)) << '\n';
    }
    

    giving output:

    i          = 00011101
    rotl(i,0)  = 00011101
    rotl(i,1)  = 00111010
    rotl(i,4)  = 11010001
    rotl(i,9)  = 00111010
    rotl(i,-1) = 10001110
    

    I'll give it a try when support arrives to GCC, GCC 9.1.0 with g++-9 -std=c++2a still doesn't support it.

    The proposal says:

    Header:

    namespace std {
      // 25.5.5, rotating   
      template
        [[nodiscard]] constexpr T rotl(T x, int s) noexcept;
      template
        [[nodiscard]] constexpr T rotr(T x, int s) noexcept;
    

    and:

    25.5.5 Rotating [bitops.rot]

    In the following descriptions, let N denote std::numeric_limits::digits.

    template
      [[nodiscard]] constexpr T rotl(T x, int s) noexcept;
    

    Constraints: T is an unsigned integer type (3.9.1 [basic.fundamental]).

    Let r be s % N.

    Returns: If r is 0, x; if r is positive, (x << r) | (x >> (N - r)); if r is negative, rotr(x, -r).

    template
      [[nodiscard]] constexpr T rotr(T x, int s) noexcept;
    

    Constraints: T is an unsigned integer type (3.9.1 [basic.fundamental]). Let r be s % N.

    Returns: If r is 0, x; if r is positive, (x >> r) | (x << (N - r)); if r is negative, rotl(x, -r).

    A std::popcount was also added to count the number of 1 bits: How to count the number of set bits in a 32-bit integer?

提交回复
热议问题