3

你能有浮动数据类型的位集容器吗?例子:

bitset<sizeof(float)*sizeof(char)> second(5.5f);
cout << second.to_string() << endl;

它不能正常工作。我想要做的是获得位表示。

4

2 回答 2

8

bitset仅将 aunsigned long作为其构造函数参数。在您的示例中,float将转换为unsigned long然后用作参数。

要获得您想要的东西,请使用以下内容:

float f = 5.5f;
std::bitset<sizeof(float)*CHAR_BIT> foo(*reinterpret_cast<unsigned long*>(&f));

这将 float 所在的“内存”重新解释为包含 an 的内存unsigned long,从而“欺骗”构造函数。

于 2011-09-23T19:30:56.750 回答
2

为了以明确定义的方式bitset从 a构建float,您应该:

  1. 确保您的类型具有兼容的尺寸;
  2. 将您的表示复制float到兼容的整数中;
  3. bitset从该整数构建一个。

这是一个最小的例子:

#include <bitset>
#include <cstring>

float f = 1.618;
static_assert(sizeof(float) <= sizeof(long long unsigned int), "wrong sizes"); // 1.
long long unsigned int f_as_int = 0;
std::memcpy(&f_as_int, &f, sizeof(float)); // 2.
std::bitset<8*sizeof(float)> f_as_bitset{f_as_int}; // 3.

long long unsigned int但是,这在大于的大字节序目标上不会按预期工作,因为无论字节序如何,位集float构造函数总是选择参数的最低有效位。这很糟糕。

所以,如果我们想要完整,我们需要解决这个问题。为此,可以将浮点数复制到相同大小 (2.) 的整数,然后(3.) 转换为 a long long unsigned int,从而得到与字节顺序无关的表示。但是,是的,与字节顺序无关的解决方案很乏味

#include <bitset>
#include <cstring>
#include <cstdint>
#include <iostream>

namespace details
{
    template<unsigned nbits> struct uint {};
    template<> struct uint<8>  { using type = uint8_t; };
    template<> struct uint<16> { using type = uint16_t; };
    template<> struct uint<32> { using type = uint32_t; };
    template<> struct uint<64> { using type = uint64_t; };
}

template<class T>
using unsigned_integer_of_same_size = typename details::uint<sizeof(T)*8>::type;

int main()
{
    float f = -1./0.;
    static_assert(sizeof(float) <= sizeof(long long unsigned int), "wrong sizes"); // 1.
    unsigned_integer_of_same_size<float> f_as_uint = 0;
    std::memcpy(&f_as_uint, &f, sizeof(float)); // 2.
    std::bitset<8*sizeof(float)> f_as_bitset{f_as_uint}; // 3. && 4.

    std::cout << f_as_bitset << "\n";
}

现场演示

于 2018-01-19T15:22:58.447 回答