如何检测128位整数类型是否可用以实现定点数乘法逻辑?
如何检测128位整数类型是否可用以实现定点数乘法逻辑?
我完全懂你现在的痛点——做定点数数学库,用64位整数存数据,乘法的时候非得靠128位整数来暂存结果才方便,不然就得把64位拆成两个32位来分步计算,既麻烦又可能影响效率。要实现你伪代码里的type_exists()逻辑,其实用C++的模板元编程或者编译器预编译宏就能搞定,下面给你两种靠谱的方案:
方案一:用SFINAE实现类型检测(C++11及以上)
这是符合C++标准的做法,利用“替换失败不是错误”的特性来判断某个类型是否存在:
#include <type_traits> // 基础模板,默认情况下类型不存在 template <typename T, typename = void> struct type_exists : std::false_type {}; // 特化版本:如果T是合法类型,就匹配这个模板 template <typename T> struct type_exists<T, std::void_t<decltype(T{})>> : std::true_type {}; // 现在可以用这个模板来检测类型了 int main() { constexpr bool has_int128 = type_exists<int128_t>::value; constexpr bool has___int128 = type_exists<__int128>::value; }
然后你就可以把这个检测逻辑用到你的类型定义里,比如用std::conditional来选择对应的math_t:
#include <type_traits> // 上面的type_exists模板... typedef int64_t storage_t; // 选择math_t类型 using math_t = std::conditional_t< type_exists<int128_t>::value, int128_t, std::conditional_t< type_exists<__int128>::value, __int128, int64_t > >; constexpr bool use_32_bit_algorithm = std::is_same_v<math_t, int64_t>;
方案二:利用编译器预定义宏(更直接)
不同编译器对128位整数的支持会有对应的预编译宏,比如GCC、Clang和ICC支持__int128,并且会定义__SIZEOF_INT128__宏;有些编译器可能支持标准的int128_t,这时候<cstdint>头文件里会有定义。你可以直接用宏来判断:
#include <cstdint> typedef int64_t storage_t; #ifdef __SIZEOF_INT128__ typedef __int128 math_t; const bool use_32_bit_algorithm = false; #elif defined(__INT128_TYPE__) typedef int128_t math_t; const bool use_32_bit_algorithm = false; #else typedef int64_t math_t; const bool use_32_bit_algorithm = true; #endif
这里要注意,__SIZEOF_INT128__是GCC系编译器用来标识__int128存在的宏,而__INT128_TYPE__则是一些编译器用来标识标准int128_t存在的宏,你可以根据目标编译器的文档调整这些宏的判断顺序。
额外小提示
如果真的走到了必须用32位拆分乘法的地步,其实也不用太头疼——把每个64位数拆成高32位和低32位,用类似大整数乘法的方法计算四个32位乘积,再把结果合并起来就行,虽然代码多一点,但逻辑是成熟的。当然如果能用上128位整数,效率肯定会高不少。
备注:内容来源于stack exchange,提问作者HiddenWindshield
相关产品推荐
相关产品推荐

