00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PPL_Float_defs_hh
00024 #define PPL_Float_defs_hh 1
00025
00026 #include "meta_programming.hh"
00027 #include "compiler.hh"
00028 #include <gmp.h>
00029 #include <cassert>
00030 #include <cmath>
00031
00032 #ifndef NAN
00033 #define NAN (HUGE_VAL - HUGE_VAL)
00034 #endif
00035
00036 namespace Parma_Polyhedra_Library {
00037
00038 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00039
00040 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00041
00042 struct float_ieee754_single {
00043 uint32_t word;
00044 static const uint32_t SGN_MASK = 0x80000000;
00045 static const uint32_t EXP_MASK = 0x7f800000;
00046 static const uint32_t POS_INF = 0x7f800000;
00047 static const uint32_t NEG_INF = 0xff800000;
00048 static const uint32_t POS_ZERO = 0x00000000;
00049 static const uint32_t NEG_ZERO = 0x80000000;
00050 static const unsigned int EXPONENT_BITS = 8;
00051 static const unsigned int MANTISSA_BITS = 23;
00052 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00053 static const int EXPONENT_BIAS = EXPONENT_MAX;
00054 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00055 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00056 - static_cast<int>(MANTISSA_BITS);
00057 int is_inf() const;
00058 int is_nan() const;
00059 int is_zero() const;
00060 int sign_bit() const;
00061 void negate();
00062 void dec();
00063 void inc();
00064 void set_max(bool negative);
00065 void build(bool negative, mpz_t mantissa, int exponent);
00066 };
00067
00068 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00069
00070 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00071
00072 struct float_ieee754_double {
00073 #ifdef PPL_WORDS_BIGENDIAN
00074 uint32_t msp;
00075 uint32_t lsp;
00076 #else
00077 uint32_t lsp;
00078 uint32_t msp;
00079 #endif
00080 static const uint32_t MSP_SGN_MASK = 0x80000000;
00081 static const uint32_t MSP_POS_INF = 0x7ff00000;
00082 static const uint32_t MSP_NEG_INF = 0xfff00000;
00083 static const uint32_t MSP_POS_ZERO = 0x00000000;
00084 static const uint32_t MSP_NEG_ZERO = 0x80000000;
00085 static const uint32_t LSP_INF = 0;
00086 static const uint32_t LSP_ZERO = 0;
00087 static const uint32_t LSP_MAX = 0xffffffff;
00088 static const unsigned int EXPONENT_BITS = 11;
00089 static const unsigned int MANTISSA_BITS = 52;
00090 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00091 static const int EXPONENT_BIAS = EXPONENT_MAX;
00092 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00093 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00094 - static_cast<int>(MANTISSA_BITS);
00095 int is_inf() const;
00096 int is_nan() const;
00097 int is_zero() const;
00098 int sign_bit() const;
00099 void negate();
00100 void dec();
00101 void inc();
00102 void set_max(bool negative);
00103 void build(bool negative, mpz_t mantissa, int exponent);
00104 };
00105
00106 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00107
00108 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00109
00110 struct float_intel_double_extended {
00111 #ifdef PPL_WORDS_BIGENDIAN
00112 uint32_t msp;
00113 uint64_t lsp;
00114 #else
00115 uint64_t lsp;
00116 uint32_t msp;
00117 #endif
00118 static const uint32_t MSP_SGN_MASK = 0x00008000;
00119 static const uint32_t MSP_POS_INF = 0x00007fff;
00120 static const uint32_t MSP_NEG_INF = 0x0000ffff;
00121 static const uint32_t MSP_POS_ZERO = 0x00000000;
00122 static const uint32_t MSP_NEG_ZERO = 0x00008000;
00123 static const uint64_t LSP_INF = 0x8000000000000000ULL;
00124 static const uint64_t LSP_ZERO = 0;
00125 static const uint64_t LSP_DMAX = 0x7fffffffffffffffULL;
00126 static const uint64_t LSP_NMAX = 0xffffffffffffffffULL;
00127 static const unsigned int EXPONENT_BITS = 15;
00128 static const unsigned int MANTISSA_BITS = 63;
00129 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00130 static const int EXPONENT_BIAS = EXPONENT_MAX;
00131 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00132 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00133 - static_cast<int>(MANTISSA_BITS);
00134 int is_inf() const;
00135 int is_nan() const;
00136 int is_zero() const;
00137 int sign_bit() const;
00138 void negate();
00139 void dec();
00140 void inc();
00141 void set_max(bool negative);
00142 void build(bool negative, mpz_t mantissa, int exponent);
00143 };
00144
00145 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00146
00147 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00148
00149 struct float_ieee754_quad {
00150 #ifdef PPL_WORDS_BIGENDIAN
00151 uint64_t msp;
00152 uint64_t lsp;
00153 #else
00154 uint64_t lsp;
00155 uint64_t msp;
00156 #endif
00157 static const uint64_t MSP_SGN_MASK = 0x8000000000000000ULL;
00158 static const uint64_t MSP_POS_INF = 0x7fff000000000000ULL;
00159 static const uint64_t MSP_NEG_INF = 0xffff000000000000ULL;
00160 static const uint64_t MSP_POS_ZERO = 0x0000000000000000ULL;
00161 static const uint64_t MSP_NEG_ZERO = 0x8000000000000000ULL;
00162 static const uint64_t LSP_INF = 0;
00163 static const uint64_t LSP_ZERO = 0;
00164 static const uint64_t LSP_MAX = 0xffffffffffffffffULL;
00165 static const unsigned int EXPONENT_BITS = 15;
00166 static const unsigned int MANTISSA_BITS = 112;
00167 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00168 static const int EXPONENT_BIAS = EXPONENT_MAX;
00169 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00170 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00171 - static_cast<int>(MANTISSA_BITS);
00172 int is_inf() const;
00173 int is_nan() const;
00174 int is_zero() const;
00175 int sign_bit() const;
00176 void negate();
00177 void dec();
00178 void inc();
00179 void set_max(bool negative);
00180 void build(bool negative, mpz_t mantissa, int exponent);
00181 };
00182
00183 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00184
00185 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00186 template <typename T>
00187 class Float : public False { };
00188
00189 #if PPL_SUPPORTED_FLOAT
00190 template <>
00191 class Float<float> : public True {
00192 public:
00193 #if PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
00194 typedef float_ieee754_single Binary;
00195 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
00196 typedef float_ieee754_double Binary;
00197 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_QUAD
00198 typedef float_ieee754_quad Binary;
00199 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_INTEL_DOUBLE_EXTENDED
00200 typedef float_intel_double_extended Binary;
00201 #else
00202 #error "invalid value for PPL_CXX_FLOAT_BINARY_FORMAT"
00203 #endif
00204 union {
00205 float number;
00206 Binary binary;
00207 } u;
00208 Float();
00209 Float(float v);
00210 float value();
00211 };
00212 #endif
00213
00214 #if PPL_SUPPORTED_DOUBLE
00215 template <>
00216 class Float<double> : public True {
00217 public:
00218 #if PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
00219 typedef float_ieee754_single Binary;
00220 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
00221 typedef float_ieee754_double Binary;
00222 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_QUAD
00223 typedef float_ieee754_quad Binary;
00224 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_INTEL_DOUBLE_EXTENDED
00225 typedef float_intel_double_extended Binary;
00226 #else
00227 #error "invalid value for PPL_CXX_DOUBLE_BINARY_FORMAT"
00228 #endif
00229 union {
00230 double number;
00231 Binary binary;
00232 } u;
00233 Float();
00234 Float(double v);
00235 double value();
00236 };
00237 #endif
00238
00239 #if PPL_SUPPORTED_LONG_DOUBLE
00240 template <>
00241 class Float<long double> : public True {
00242 public:
00243 #if PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
00244 typedef float_ieee754_single Binary;
00245 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
00246 typedef float_ieee754_double Binary;
00247 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_QUAD
00248 typedef float_ieee754_quad Binary;
00249 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_INTEL_DOUBLE_EXTENDED
00250 typedef float_intel_double_extended Binary;
00251 #else
00252 #error "invalid value for PPL_CXX_LONG_DOUBLE_BINARY_FORMAT"
00253 #endif
00254 union {
00255 long double number;
00256 Binary binary;
00257 } u;
00258 Float();
00259 Float(long double v);
00260 long double value();
00261 };
00262 #endif
00263
00264 }
00265
00266 #include "Float.inlines.hh"
00267
00268 #endif // !defined(PPL_Float_defs_hh)