我使用std::bitset表示短DNA序列(单倍型)。
出于我的目的,我需要能够将每个这样的序列转换为单个整数。目前,这一要求似乎将我的序列限制为长度<=64因为std::bitset::to_ullong的工作方式
P>因为在C++中有128种表示整数的方法(C++中有128位整数)吗?我想知道STD::BITSET支持直接转换为128位整数的时间需要多长时间?
当然,我会非常高兴地知道我错了,而且人们已经可以这么做了
谢谢
您可以随时提供自己的:
#包括<;climits>;
#包括<;cstdint>;
#包括<;限制>;
#包括<;比特集>;
静态断言(sizeof(unsigned long)==8&字符位==8);
结构我的uint128{
标准:uint64_t lo;
标准:uint64_t hi;
};
模板<;标准:尺寸;
我的uint128到uint128(常量标准::位集<;N>;&v){
constexpr std::bitset<;N>;掩码(std::numeric_limits<;std::uint64_t>;::max());
std::uint64_t lo=(v&;mask).to_ullong();
std::uint64_t hi=((v>;>;64)和掩码)。到_ullong();
返回{lo,hi};
}
但是,这会产生一些技术上不安全的假设,例如无符号long-long为64位。static\u assert有帮助,但更好的解决方案是实际考虑可能的差异:
#包括<;climits>;
#包括<;限制>;
#包括<;比特集>;
#包括<;阵列>;
模板<;标准::大小\u t位>;
构造我的单元{
静态constexpr std::size\t num\u parts=
(位/CHAR\u位+(位%CHAR\u位>;0))/sizeof(无符号长);
长部件数组<;长部件>;
模板<;标准::尺寸&u t N,标准::尺寸&u t I>;
从位集填充空(常量标准::位集<;N>;&v){
constexpr std::size\u t offset=I*CHAR\u BIT*sizeof(无符号长);
constexpr std::bitset<;N>;掩码(std::numeric_limits<;unsigned long>;::max());
零件[I]=((v>;>;偏移量)和遮罩)。至_ullong();
if constexpr(I+1<;num_零件){
从\u位集<;N,I+1>;(v)填充\u;
}
}
};
模板<;标准:尺寸;
我的单位<;128>;到uint128(常数标准::位集<;N>;&v){
我的uint<;128>;结果;
结果。从\u位集<;N,0>;(v)填充\u;
返回结果;
}
自动tmp_a=&;至uint128<;16>;;
自动tmp_b=&;至uint128<;65>;;
自动tmp_c=&;至uint128<;128>;;
gcc和clang都对此进行了优化,以充分清洁X86-64上的组件:
my\u uint128\u t to\u uint128\u t<;16ul>;(标准::位集<;16ul>;常数&;):
movzx edx,字PTR[rdi]
异或eax,eax
ret
我的uint128到uint128<;65ul>;(标准::位集<;65ul>;常数&;):
mov-rdx,QWORD-PTR[rdi]
mov-rax,QWORD-PTR[rdi+8]
ret
我的uint128到uint128<;128ul>;(标准::位集<;128ul>;常数&;):
mov-rdx,QWORD-PTR[rdi]
mov-rax,QWORD-PTR[rdi+8]
ret
参见导栓上的说明
注:
- 这取决于以某种方式实现的标准库。虽然它可以保证工作正常,但没有任何形式的保证可以保证性能的一致性
my\u uint128\u t在这里有点像占位符类型。要将其正确用作可移植的128位整数,仍然需要一些endianness处理- 为什么是这样,正确地处理非典型整数类型会导致一团混乱