c++ - C++ 中循环移位(旋转)操作的最佳实践

标签 c++ c rotation bit-manipulation c++-faq

左移和右移运算符(<< 和 >>)在 C++ 中已经可用。
但是,我不知道如何执行循环移位或旋转操作。

如何执行“向左旋转”和“向右旋转”等操作?

在这里向右旋转两次

Initial --> 1000 0011 0100 0010

应该导致:
Final   --> 1010 0000 1101 0000

一个例子会很有帮助。

(编者注:如果旋转计数为零,或者编译为不仅仅是单个旋转机器指令,则在 C 中表达旋转的许多常见方式都会遭受未定义的行为。这个问题的答案应该记录最佳实践。)

最佳答案

C++20 std::rotlstd::rotr

它已经到了! http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html并将其添加到 <bit>标题。

cppreference says用法如下:

#include <bit>
#include <bitset>
#include <cstdint>
#include <iostream>

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';
}

给出输出:
i          = 00011101
rotl(i,0)  = 00011101
rotl(i,1)  = 00111010
rotl(i,4)  = 11010001
rotl(i,9)  = 00111010
rotl(i,-1) = 10001110

当支持到达 GCC,GCC 9.1.0 时,我会试一试 g++-9 -std=c++2a仍然不支持它。

该提案说:

Header:

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


和:

25.5.5 Rotating [bitops.rot]

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

template<class T>
  [[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<class T>
  [[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).



一个 std::popcount还添加了计算 1 位的数量:How to count the number of set bits in a 32-bit integer?

关于c++ - C++ 中循环移位(旋转)操作的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/776508/

相关文章:

javascript - 添加此 JavaScript 代码的链接

c++ - 如何使用 TIdHTTPProxyServer 重定向 Post 请求

c++ - 交换链表的相邻元素

c++ - 如何在单独的源文件中定义模板函数并仅包含标题调用它

c++ - 判断Unicode字符串是否在C++中具有唯一字符的最有效方法是什么?

c - 给定大于 256 的整数,如何在 C 中将整数转换为无符号字符?

ios - 尝试拖放对象时旋转 UIView iOS 错误

iOS 11 强制 UIViewController 到纵向模式不起作用

C、字符串数组不会弃用从字符串常量到 'char*' 的转换

c - 带有 pthread 的简单 Linux C/S 套接字