我不得不做一些肮脏的把戏,在应用程序中传递一个std::uint64_t。不幸的是,我只能使用std::vector<float>。据我所知,float在大多数平台上都是32位的,所以应该可以将64位的std::uint64_t拆分为两个32位的int,将它们表示为float,将它们放入向量中,并在另一端反转该过程。我该怎么做?
std::uint64_t
std::vector<float>
float
628mspwn1#
快速和肮脏,但标准的兼容,如果我没有弄错:
#include <cassert> // using assert #include <cstdint> // using std::uint64_t #include <cstring> // using std::memcpy #include <vector> std::vector<float> pack(std::uint64_t value) { static_assert(sizeof(value) >= sizeof(float)); static_assert(sizeof(value) % sizeof(float) == 0); std::vector<float> rtrn(sizeof(value) / sizeof(float)); std::memcpy(rtrn.data(), &value, sizeof(value)); return rtrn; } std::uint64_t unpack(const std::vector<float>& packed) { std::uint64_t rtrn; assert(packed.size() == sizeof(rtrn) / sizeof(float)); std::memcpy(&rtrn, packed.data(), sizeof(rtrn)); return rtrn; }
字符串
tct7dpnv2#
C++23:
#include <bit> #include <array> #include <ranges> #include <vector> std::unint64_t ui64{whatever()}; auto vec = std::bit_cast< std::array<float, 2> >(ui64) | std::ranges::to<std::vector>();
字符串bit_cast需要C20,ranges::to需要C23。你也可以使用传统的vector::vector(begin, end)构造函数来转换数组,但是ranges::to更可读,更不容易打字。
bit_cast
ranges::to
vector::vector(begin, end)
往复例程:
std::vector<float> const flt_vec = {float1(), float2()}; std::array<float,2> flt_arr{}; for(auto&& [a,v] : std::views::zip(flt_arr, vec_arr)) a=v; auto ui64 = std::bit_cast<std::uint64_t>(flt_arr);
型在尝试任何操作之前,您可以检查float和uint64_t的大小是否匹配,或者应该为bit_cast使用另一种介质类型:
uint64_t
static_assert(sizeof(std::uint64_t)==sizeof(std::array<float, 2>));
型在C20之前,std::memcpy是C中唯一可靠的类型双关方法;但是这个函数有众所周知的缺陷,不鼓励在用户代码中使用它。为了所有相关的UB,因此C++20引入了std::bit_cast作为constexpr可靠的编译器魔法,用于类型-如果sizeof source和destination相等,则此函数返回与源对象具有完全相同位模式的destination类型的值。
std::memcpy
std::bit_cast
constexpr
sizeof
2条答案
按热度按时间628mspwn1#
快速和肮脏,但标准的兼容,如果我没有弄错:
字符串
tct7dpnv2#
C++23:
字符串
bit_cast
需要C20,ranges::to
需要C23。你也可以使用传统的vector::vector(begin, end)
构造函数来转换数组,但是ranges::to
更可读,更不容易打字。往复例程:
型
在尝试任何操作之前,您可以检查
float
和uint64_t
的大小是否匹配,或者应该为bit_cast
使用另一种介质类型:型
在C20之前,
std::memcpy
是C中唯一可靠的类型双关方法;但是这个函数有众所周知的缺陷,不鼓励在用户代码中使用它。为了所有相关的UB,因此C++20引入了std::bit_cast
作为constexpr
可靠的编译器魔法,用于类型-如果sizeof
source和destination相等,则此函数返回与源对象具有完全相同位模式的destination类型的值。