std::bit_cast în C++

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).

Sintaxă
constexpr To bit_cast(const From& sursa) noexcept;

Ce face std::bit_cast

std::bit_cast<Destinatie>(x) copiază biții lui x într-un obiect de alt tip, fără conversie de valoare. De exemplu, biții numărului 1.0f văzuți ca întreg dau 1065353216 (0x3f800000), modul în care este stocat în standardul IEEE 754.

Cele două tipuri trebuie să aibă aceeași mărime și să poată fi copiate octet cu octet. Înlocuiește trucurile vechi cu reinterpret_cast sau union, care sunt comportament nedefinit.

Parametri

Parametru Descriere
To Tipul destinație (aceeași mărime ca sursa).
sursa Obiectul ai cărui biți sunt copiați.

Ce returnează

Un obiect de tip To cu aceiași biți.

Exemple

Exemplul 1: Cum arată un float în memorie

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

int main() {
    for (float f : {1.0f, -2.5f, 0.1f}) {
        auto biti = std::bit_cast<std::uint32_t>(f);
        std::println("{:>5} -> 0x{:08x} = {:032b}", f, biti, biti);
    }
}

Rezultat

    1 -> 0x3f800000 = 00111111100000000000000000000000
 -2.5 -> 0xc0200000 = 11000000001000000000000000000000
  0.1 -> 0x3dcccccd = 00111101110011001100110011001101

Exemplul 2: Înapoi: din biți în float

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

int main() {
    std::uint32_t biti = 0x40490fdb;
    float f = std::bit_cast<float>(biti);
    std::println("{}", f);

    double d = 3.14;
    auto inapoi = std::bit_cast<double>(std::bit_cast<std::uint64_t>(d));
    std::println("Dus-întors: {}", inapoi);
}

Rezultat

3.1415927
Dus-întors: 3.14

Greșeli frecvente

  • Folosești *reinterpret_cast<std::uint32_t*>(&f): încalcă regulile de aliasing, deci este comportament nedefinit. std::bit_cast este varianta corectă.
  • Confunzi bit_cast cu static_cast: static_cast<int>(2.5f) dă 2, iar bit_cast dă biții.

Comenzi înrudite

  • std::rotl: 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ă.
  • std::numeric_limits: Dă proprietățile unui tip numeric: valoarea maximă și minimă, precizia, dacă are semn, infinitul.
  • std::popcount: Numără câți biți de 1 are un număr întreg fără semn.