std::rotl în C++

Rotește biții unui număr fără semn spre stânga (rotl) sau spre dreapta (rotr); biții care ies pe o parte intră pe cealaltă.

Sintaxă
constexpr T rotl(T x, int s) noexcept;
constexpr T rotr(T x, int s) noexcept;

Ce face std::rotl

Spre deosebire de deplasarea <<, care pierde biții ieșiți din număr, rotirea îi aduce înapoi la celălalt capăt. std::rotl(x, s) rotește cu s poziții spre stânga, std::rotr spre dreapta. Un s negativ inversează sensul.

Rotirile apar în funcții de hash, generatoare de numere aleatorii și algoritmi de criptografie. Rezultatul depinde de lățimea tipului: rotirea unui std::uint8_t se face pe 8 biți.

Parametri

Parametru Descriere
x Un întreg fără semn.
s Numărul de poziții.

Ce returnează

Valoarea rotită, de același tip.

Exemple

Exemplul 1: Rotire față de deplasare

#include <bit>
#include <cstdint>
#include <print>

int main() {
    std::uint8_t x = 0b10010110;

    std::println("x          = {:08b}", x);
    std::println("rotl(x, 2) = {:08b}", std::rotl(x, 2));
    std::println("rotr(x, 2) = {:08b}", std::rotr(x, 2));
    std::println("x << 2     = {:08b}", static_cast<std::uint8_t>(x << 2));
}

Rezultat

x          = 10010110
rotl(x, 2) = 01011010
rotr(x, 2) = 10100101
x << 2     = 01011000

Exemplul 2: Un hash simplu pentru texte

Rezultatul este același la fiecare rulare, pentru că depinde doar de text.

#include <bit>
#include <cstdint>
#include <print>
#include <string_view>

std::uint32_t hash_text(std::string_view text) {
    std::uint32_t h = 2166136261u;
    for (unsigned char c : text) {
        h = std::rotl(h, 5) ^ c;
    }
    return h;
}

int main() {
    for (std::string_view s : {"Ana", "ana", "Iași"}) {
        std::println("{:<5} {:08x}", s, hash_text(s));
    }
}

Rezultat

Ana   4ee3c92f
ana   4ee3492f
Iași  8fa18a72

Greșeli frecvente

  • Rotești un int cu semn: nu compilează. Folosește un tip fără semn de lățimea dorită.

Comenzi înrudite

  • std::popcount: Numără câți biți de 1 are un număr întreg fără semn.
  • std::bit_cast: Reinterpretează biții unui obiect ca alt tip de aceeași mărime, în mod sigur (de exemplu biții unui float ca uint32_t).
  • std::bit_width: Returnează câți biți sunt necesari pentru a reprezenta un număr fără semn (0 pentru 0).