📄 fp_traits.hpp
字号:
static void init() {} static void get_bits(double x, uint64_t& a) { memcpy(&a, &x, 8); } static void set_bits(double& x, uint64_t a) { memcpy(&x, &a, 8); }};#endif// long double (64 bits) -------------------------------------------------------#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)template<> struct fp_traits_impl<long double, double_precision_tag>{ typedef uint32_t bits; typedef not_all_bits coverage; BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000); BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000); BOOST_STATIC_CONSTANT(uint32_t, flag = 0); BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff); static void init() {} static void get_bits(long double x, uint32_t& a) { memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4); } static void set_bits(long double& x, uint32_t a) { memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4); }private:#if defined(BOOST_BIG_ENDIAN) BOOST_STATIC_CONSTANT(int, offset_ = 0);#elif defined(BOOST_LITTLE_ENDIAN) BOOST_STATIC_CONSTANT(int, offset_ = 4);#else BOOST_STATIC_ASSERT(false);#endif};//..............................................................................#elsetemplate<> struct fp_traits_impl<long double, double_precision_tag>{ typedef uint64_t bits; typedef all_bits coverage; static const uint64_t sign = (uint64_t)0x80000000 << 32; static const uint64_t exponent = (uint64_t)0x7ff00000 << 32; static const uint64_t flag = 0; static const uint64_t mantissa = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff; static void init() {} static void get_bits(long double x, uint64_t& a) { memcpy(&a, &x, 8); } static void set_bits(long double& x, uint64_t a) { memcpy(&x, &a, 8); }};#endif// long double (>64 bits), x86 and x64 -----------------------------------------#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \ || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \ || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)// Intel extended double precision format (80 bits)template<> struct fp_traits_impl<long double, extended_double_precision_tag>{ typedef uint32_t bits; typedef not_all_bits coverage; BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000); BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000); BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000); BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff); static void init() {} static void get_bits(long double x, uint32_t& a) { memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4); } static void set_bits(long double& x, uint32_t a) { memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4); }};// long double (>64 bits), Itanium ---------------------------------------------#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)// The floating point format is unknown at compile time// No template specialization is provided.// The generic definition is used.// The Itanium supports both// the Intel extended double precision format (80 bits) and// the IEEE extended double precision format with 15 exponent bits (128 bits).// long double (>64 bits), PowerPC ---------------------------------------------#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \ || defined(__ppc) || defined(__ppc__) || defined(__PPC__)// PowerPC extended double precision format (128 bits)template<> struct fp_traits_impl<long double, extended_double_precision_tag>{ typedef uint32_t bits; typedef not_all_bits coverage; BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000); BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000); BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000); BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff); static void init() {} static void get_bits(long double x, uint32_t& a) { memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4); } static void set_bits(long double& x, uint32_t a) { memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4); }private:#if defined(BOOST_BIG_ENDIAN) BOOST_STATIC_CONSTANT(int, offset_ = 0);#elif defined(BOOST_LITTLE_ENDIAN) BOOST_STATIC_CONSTANT(int, offset_ = 12);#else BOOST_STATIC_ASSERT(false);#endif};// long double (>64 bits), Motorola 68K ----------------------------------------#elif defined(__m68k) || defined(__m68k__) \ || defined(__mc68000) || defined(__mc68000__) \// Motorola extended double precision format (96 bits)// It is the same format as the Intel extended double precision format,// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and// 3) the flag bit is not set for infinitytemplate<> struct fp_traits_impl<long double, extended_double_precision_tag>{ typedef uint32_t bits; typedef not_all_bits coverage; BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000); BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000); BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000); BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff); static void init() {} // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding. static void get_bits(long double x, uint32_t& a) { memcpy(&a, &x, 2); memcpy(reinterpret_cast<unsigned char*>(&a) + 2, reinterpret_cast<const unsigned char*>(&x) + 4, 2); } static void set_bits(long double& x, uint32_t a) { memcpy(&x, &a, 2); memcpy(reinterpret_cast<unsigned char*>(&x) + 4, reinterpret_cast<const unsigned char*>(&a) + 2, 2); }};// long double (>64 bits), All other processors --------------------------------#else// IEEE extended double precision format with 15 exponent bits (128 bits)template<> struct fp_traits_impl<long double, extended_double_precision_tag>{ typedef uint32_t bits; typedef not_all_bits coverage; BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000); BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000); BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000); BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x0000ffff); static void init() {} static void get_bits(long double x, uint32_t& a) { memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4); } static void set_bits(long double& x, uint32_t a) { memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4); }private:#if defined(BOOST_BIG_ENDIAN) BOOST_STATIC_CONSTANT(int, offset_ = 0);#elif defined(BOOST_LITTLE_ENDIAN) BOOST_STATIC_CONSTANT(int, offset_ = 12);#else BOOST_STATIC_ASSERT(false);#endif};#endif//------------------------------------------------------------------------------// size_to_precision is a type switch for converting a C++ floating point type// to the corresponding precision type.template<int n> struct size_to_precision;template<> struct size_to_precision<4>{ typedef single_precision_tag type;};template<> struct size_to_precision<8>{ typedef double_precision_tag type;};template<> struct size_to_precision<10>{ typedef extended_double_precision_tag type;};template<> struct size_to_precision<12>{ typedef extended_double_precision_tag type;};template<> struct size_to_precision<16>{ typedef extended_double_precision_tag type;};// fp_traits is a type switch that selects the right fp_traits_impltemplate<class T> struct fp_traits{ BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value); typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T)>::type precision; typedef fp_traits_impl<T, precision> type;};//------------------------------------------------------------------------------} // namespace detail} // namespace math} // namespace boost#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -