Warning, file /include/boost/numeric/interval/detail/msvc_rounding_control.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_MSVC_ROUNDING_CONTROL_HPP
0012 #define BOOST_NUMERIC_INTERVAL_DETAIL_MSVC_ROUNDING_CONTROL_HPP
0013
0014 #ifndef _MSC_VER
0015 # error This header is only intended for MSVC, but might work for Borland as well
0016 #endif
0017
0018 #include <float.h> // MSVC rounding control
0019
0020
0021
0022
0023 namespace boost {
0024 namespace numeric {
0025 namespace interval_lib {
0026 namespace detail {
0027
0028 #if BOOST_MSVC < 1400 || defined(_WIN64)
0029 extern "C" { double rint(double); }
0030 #else
0031 inline double rint(double x)
0032 {
0033 _asm FLD [x] ;
0034 _asm FRNDINT ;
0035
0036 }
0037 #endif
0038
0039 struct x86_rounding
0040 {
0041 static unsigned int hard2msvc(unsigned short m) {
0042 unsigned int n = 0;
0043 if (m & 0x01) n |= _EM_INVALID;
0044 if (m & 0x02) n |= _EM_DENORMAL;
0045 if (m & 0x04) n |= _EM_ZERODIVIDE;
0046 if (m & 0x08) n |= _EM_OVERFLOW;
0047 if (m & 0x10) n |= _EM_UNDERFLOW;
0048 if (m & 0x20) n |= _EM_INEXACT;
0049 switch (m & 0x300) {
0050 case 0x000: n |= _PC_24; break;
0051 case 0x200: n |= _PC_53; break;
0052 case 0x300: n |= _PC_64; break;
0053 }
0054 switch (m & 0xC00) {
0055 case 0x000: n |= _RC_NEAR; break;
0056 case 0x400: n |= _RC_DOWN; break;
0057 case 0x800: n |= _RC_UP; break;
0058 case 0xC00: n |= _RC_CHOP; break;
0059 }
0060 if (m & 0x1000) n |= _IC_AFFINE;
0061 return n;
0062 }
0063
0064 static unsigned short msvc2hard(unsigned int n) {
0065 unsigned short m = 0;
0066 if (n & _EM_INVALID) m |= 0x01;
0067 if (n & _EM_DENORMAL) m |= 0x02;
0068 if (n & _EM_ZERODIVIDE) m |= 0x04;
0069 if (n & _EM_OVERFLOW) m |= 0x08;
0070 if (n & _EM_UNDERFLOW) m |= 0x10;
0071 if (n & _EM_INEXACT) m |= 0x20;
0072 switch (n & _MCW_RC) {
0073 case _RC_NEAR: m |= 0x000; break;
0074 case _RC_DOWN: m |= 0x400; break;
0075 case _RC_UP: m |= 0x800; break;
0076 case _RC_CHOP: m |= 0xC00; break;
0077 }
0078 switch (n & _MCW_PC) {
0079 case _PC_24: m |= 0x000; break;
0080 case _PC_53: m |= 0x200; break;
0081 case _PC_64: m |= 0x300; break;
0082 }
0083 if ((n & _MCW_IC) == _IC_AFFINE) m |= 0x1000;
0084 return m;
0085 }
0086
0087 typedef unsigned short rounding_mode;
0088 static void get_rounding_mode(rounding_mode& mode)
0089 { mode = msvc2hard(_control87(0, 0)); }
0090 static void set_rounding_mode(const rounding_mode mode)
0091 {
0092 _control87(hard2msvc(mode),
0093 _MCW_EM | _MCW_RC
0094 #if !defined(_M_AMD64) && !defined(_M_ARM) && !defined(_M_ARM64)
0095
0096
0097
0098
0099
0100
0101 | _MCW_PC | _MCW_IC
0102 #endif
0103 );
0104 }
0105 static double to_int(const double& x) { return rint(x); }
0106 };
0107
0108 }
0109 }
0110 }
0111 }
0112
0113 #endif