gpt4 book ai didi

c++ - 是否希望在不久的将来将 std::bitset<128> 转换为单个 128 位整数?

转载 作者:行者123 更新时间:2023-12-02 01:54:22 30 4
gpt4 key购买 nike

我使用 std::bitset 来表示短 DNA 序列(单倍型)。出于我的目的,我需要能够将每个这样的序列转换为单个整数。目前,由于 std::bitset::to_ullong 的工作方式,此要求似乎将我的序列长度限制为 <=64?

由于 C++ 有多种表示 128 位整数的方法( Is there a 128 bit integer in C++? ),我想知道 std::bitset 还需要多长时间才能支持直接转换为 128 位整数?

当然,如果我知道我错了并且人们已经可以做到这一点,我会非常高兴......

谢谢!

最佳答案

您始终可以提供自己的:

#include <climits>
#include <cstdint>
#include <limits>
#include <bitset>

static_assert(sizeof(unsigned long long) == 8 && CHAR_BIT == 8);

struct my_uint128_t {
std::uint64_t lo;
std::uint64_t hi;
};

template<std::size_t N>
my_uint128_t to_uint128_t(const std::bitset<N>& v) {
constexpr std::bitset<N> mask(std::numeric_limits<std::uint64_t>::max());
std::uint64_t lo = (v & mask).to_ullong();
std::uint64_t hi = ((v >> 64) & mask).to_ullong();

return {lo, hi};
}

但是,这会产生一些技术上不安全的假设,例如 unsigned long long 为 64 位。 static_assert 有帮助,但更好的解决方案是实际考虑可能的差异:

#include <climits>
#include <limits>
#include <bitset>
#include <array>

template<std::size_t BITS>
struct my_uint_t {
static constexpr std::size_t num_parts =
(BITS / CHAR_BIT + (BITS % CHAR_BIT > 0)) / sizeof(unsigned long long);
std::array<unsigned long long, num_parts> parts;

template<std::size_t N, std::size_t I>
void populate_from_bitset(const std::bitset<N>& v) {
constexpr std::size_t offset = I * CHAR_BIT * sizeof(unsigned long long);
constexpr std::bitset<N> mask(std::numeric_limits<unsigned long long>::max());

parts[I] = ((v >> offset) & mask).to_ullong();
if constexpr(I + 1 < num_parts) {
populate_from_bitset<N, I + 1>(v);
}
}
};

template<std::size_t N>
my_uint_t<128> to_uint128_t(const std::bitset<N>& v) {

my_uint_t<128> result;
result.populate_from_bitset<N, 0>(v);

return result;
}

auto tmp_a = &to_uint128_t<16>;
auto tmp_b = &to_uint128_t<65>;
auto tmp_c = &to_uint128_t<128>;

gcc 和 clang 都对此进行了优化,以充分清理 X86-64 上的程序集:

my_uint128_t to_uint128_t<16ul>(std::bitset<16ul> const&):
movzx edx, WORD PTR [rdi]
xor eax, eax
ret
my_uint128_t to_uint128_t<65ul>(std::bitset<65ul> const&):
mov rdx, QWORD PTR [rdi]
mov rax, QWORD PTR [rdi+8]
ret
my_uint128_t to_uint128_t<128ul>(std::bitset<128ul> const&):
mov rdx, QWORD PTR [rdi]
mov rax, QWORD PTR [rdi+8]
ret

参见godbolt

注释:

  • 这依赖于以某种方式实现的标准库。虽然可以保证其正常工作,但没有正式保证性能将保持一致。
  • my_uint128_t 在这里有点占位符类型。仍需要进行一些字节序处理才能正确地将其用作可移植的 128 位整数。
  • 为什么,正确处理非典型整数类型会导致一片困惑。

关于c++ - 是否希望在不久的将来将 std::bitset<128> 转换为单个 128 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69799748/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com