00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_Float_defs_hh
00025 #define PPL_Float_defs_hh 1
00026
00027 #include "meta_programming.hh"
00028 #include "compiler.hh"
00029 #include <gmp.h>
00030 #include "assert.hh"
00031 #include <cmath>
00032
00033 #ifdef NAN
00034 #define PPL_NAN NAN
00035 #else
00036 #define PPL_NAN (HUGE_VAL - HUGE_VAL)
00037 #endif
00038
00039 namespace Parma_Polyhedra_Library {
00040
00041 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00042
00043 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00044
00045 struct float_ieee754_half {
00046 uint16_t word;
00047 static const uint16_t SGN_MASK = 0x8000;
00048 static const uint16_t EXP_MASK = 0xfc00;
00049 static const uint16_t POS_INF = 0xfc00;
00050 static const uint16_t NEG_INF = 0x7c00;
00051 static const uint16_t POS_ZERO = 0x0000;
00052 static const uint16_t NEG_ZERO = 0x8000;
00053 static const unsigned int BASE = 2;
00054 static const unsigned int EXPONENT_BITS = 5;
00055 static const unsigned int MANTISSA_BITS = 10;
00056 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00057 static const int EXPONENT_BIAS = EXPONENT_MAX;
00058 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00059 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00060 - static_cast<int>(MANTISSA_BITS);
00061 int is_inf() const;
00062 int is_nan() const;
00063 int is_zero() const;
00064 int sign_bit() const;
00065 void negate();
00066 void dec();
00067 void inc();
00068 void set_max(bool negative);
00069 void build(bool negative, mpz_t mantissa, int exponent);
00070
00071 };
00072
00073 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00074
00075 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00076
00077 struct float_ieee754_single {
00078 uint32_t word;
00079 static const uint32_t SGN_MASK = 0x80000000;
00080 static const uint32_t EXP_MASK = 0x7f800000;
00081 static const uint32_t POS_INF = 0x7f800000;
00082 static const uint32_t NEG_INF = 0xff800000;
00083 static const uint32_t POS_ZERO = 0x00000000;
00084 static const uint32_t NEG_ZERO = 0x80000000;
00085 static const unsigned int BASE = 2;
00086 static const unsigned int EXPONENT_BITS = 8;
00087 static const unsigned int MANTISSA_BITS = 23;
00088 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00089 static const int EXPONENT_BIAS = EXPONENT_MAX;
00090 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00091 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00092 - static_cast<int>(MANTISSA_BITS);
00093 int is_inf() const;
00094 int is_nan() const;
00095 int is_zero() const;
00096 int sign_bit() const;
00097 void negate();
00098 void dec();
00099 void inc();
00100 void set_max(bool negative);
00101 void build(bool negative, mpz_t mantissa, int exponent);
00102 };
00103
00104 #ifdef WORDS_BIGENDIAN
00105 #ifndef PPL_WORDS_BIGENDIAN
00106 #define PPL_WORDS_BIGENDIAN
00107 #endif
00108 #endif
00109
00110 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00111
00112 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00113
00114 struct float_ieee754_double {
00115 #ifdef PPL_WORDS_BIGENDIAN
00116 uint32_t msp;
00117 uint32_t lsp;
00118 #else
00119 uint32_t lsp;
00120 uint32_t msp;
00121 #endif
00122 static const uint32_t MSP_SGN_MASK = 0x80000000;
00123 static const uint32_t MSP_POS_INF = 0x7ff00000;
00124 static const uint32_t MSP_NEG_INF = 0xfff00000;
00125 static const uint32_t MSP_POS_ZERO = 0x00000000;
00126 static const uint32_t MSP_NEG_ZERO = 0x80000000;
00127 static const uint32_t LSP_INF = 0;
00128 static const uint32_t LSP_ZERO = 0;
00129 static const uint32_t LSP_MAX = 0xffffffff;
00130 static const unsigned int BASE = 2;
00131 static const unsigned int EXPONENT_BITS = 11;
00132 static const unsigned int MANTISSA_BITS = 52;
00133 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00134 static const int EXPONENT_BIAS = EXPONENT_MAX;
00135 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00136 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00137 - static_cast<int>(MANTISSA_BITS);
00138 int is_inf() const;
00139 int is_nan() const;
00140 int is_zero() const;
00141 int sign_bit() const;
00142 void negate();
00143 void dec();
00144 void inc();
00145 void set_max(bool negative);
00146 void build(bool negative, mpz_t mantissa, int exponent);
00147 };
00148
00149 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00150
00151 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00152
00153 struct float_ibm_single {
00154 uint32_t word;
00155 static const uint32_t SGN_MASK = 0x80000000;
00156 static const uint32_t EXP_MASK = 0x7f000000;
00157 static const uint32_t POS_INF = 0x7f000000;
00158 static const uint32_t NEG_INF = 0xff000000;
00159 static const uint32_t POS_ZERO = 0x00000000;
00160 static const uint32_t NEG_ZERO = 0x80000000;
00161 static const unsigned int BASE = 16;
00162 static const unsigned int EXPONENT_BITS = 7;
00163 static const unsigned int MANTISSA_BITS = 24;
00164 static const int EXPONENT_BIAS = 64;
00165 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00166 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00167 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00168 - static_cast<int>(MANTISSA_BITS);
00169 int is_inf() const;
00170 int is_nan() const;
00171 int is_zero() const;
00172 int sign_bit() const;
00173 void negate();
00174 void dec();
00175 void inc();
00176 void set_max(bool negative);
00177 void build(bool negative, mpz_t mantissa, int exponent);
00178 };
00179
00180 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00181
00182 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00183
00184 struct float_ibm_double {
00185 static const unsigned int BASE = 16;
00186 static const unsigned int EXPONENT_BITS = 7;
00187 static const unsigned int MANTISSA_BITS = 56;
00188 static const int EXPONENT_BIAS = 64;
00189 };
00190
00191 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00192
00193 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00194
00195 struct float_intel_double_extended {
00196 #ifdef PPL_WORDS_BIGENDIAN
00197 uint32_t msp;
00198 uint64_t lsp;
00199 #else
00200 uint64_t lsp;
00201 uint32_t msp;
00202 #endif
00203 static const uint32_t MSP_SGN_MASK = 0x00008000;
00204 static const uint32_t MSP_POS_INF = 0x00007fff;
00205 static const uint32_t MSP_NEG_INF = 0x0000ffff;
00206 static const uint32_t MSP_POS_ZERO = 0x00000000;
00207 static const uint32_t MSP_NEG_ZERO = 0x00008000;
00208 static const uint64_t LSP_INF = 0x8000000000000000ULL;
00209 static const uint64_t LSP_ZERO = 0;
00210 static const uint64_t LSP_DMAX = 0x7fffffffffffffffULL;
00211 static const uint64_t LSP_NMAX = 0xffffffffffffffffULL;
00212 static const unsigned int BASE = 2;
00213 static const unsigned int EXPONENT_BITS = 15;
00214 static const unsigned int MANTISSA_BITS = 63;
00215 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00216 static const int EXPONENT_BIAS = EXPONENT_MAX;
00217 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00218 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00219 - static_cast<int>(MANTISSA_BITS);
00220 int is_inf() const;
00221 int is_nan() const;
00222 int is_zero() const;
00223 int sign_bit() const;
00224 void negate();
00225 void dec();
00226 void inc();
00227 void set_max(bool negative);
00228 void build(bool negative, mpz_t mantissa, int exponent);
00229 };
00230
00231 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00232
00233 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00234
00235 struct float_ieee754_quad {
00236 #ifdef PPL_WORDS_BIGENDIAN
00237 uint64_t msp;
00238 uint64_t lsp;
00239 #else
00240 uint64_t lsp;
00241 uint64_t msp;
00242 #endif
00243 static const uint64_t MSP_SGN_MASK = 0x8000000000000000ULL;
00244 static const uint64_t MSP_POS_INF = 0x7fff000000000000ULL;
00245 static const uint64_t MSP_NEG_INF = 0xffff000000000000ULL;
00246 static const uint64_t MSP_POS_ZERO = 0x0000000000000000ULL;
00247 static const uint64_t MSP_NEG_ZERO = 0x8000000000000000ULL;
00248 static const uint64_t LSP_INF = 0;
00249 static const uint64_t LSP_ZERO = 0;
00250 static const uint64_t LSP_MAX = 0xffffffffffffffffULL;
00251 static const unsigned int BASE = 2;
00252 static const unsigned int EXPONENT_BITS = 15;
00253 static const unsigned int MANTISSA_BITS = 112;
00254 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
00255 static const int EXPONENT_BIAS = EXPONENT_MAX;
00256 static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
00257 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
00258 - static_cast<int>(MANTISSA_BITS);
00259 int is_inf() const;
00260 int is_nan() const;
00261 int is_zero() const;
00262 int sign_bit() const;
00263 void negate();
00264 void dec();
00265 void inc();
00266 void set_max(bool negative);
00267 void build(bool negative, mpz_t mantissa, int exponent);
00268 };
00269
00270 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00271
00272 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00273 template <typename T>
00274 class Float : public False { };
00275
00276 #if PPL_SUPPORTED_FLOAT
00277 template <>
00278 class Float<float> : public True {
00279 public:
00280 #if PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_HALF
00281 typedef float_ieee754_half Binary;
00282 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
00283 typedef float_ieee754_single Binary;
00284 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
00285 typedef float_ieee754_double Binary;
00286 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IBM_SINGLE
00287 typedef float_ibm_single Binary;
00288 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_QUAD
00289 typedef float_ieee754_quad Binary;
00290 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_INTEL_DOUBLE_EXTENDED
00291 typedef float_intel_double_extended Binary;
00292 #else
00293 #error "invalid value for PPL_CXX_FLOAT_BINARY_FORMAT"
00294 #endif
00295 union {
00296 float number;
00297 Binary binary;
00298 } u;
00299 Float();
00300 Float(float v);
00301 float value();
00302 };
00303 #endif
00304
00305 #if PPL_SUPPORTED_DOUBLE
00306 template <>
00307 class Float<double> : public True {
00308 public:
00309 #if PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_HALF
00310 typedef float_ieee754_half Binary;
00311 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
00312 typedef float_ieee754_single Binary;
00313 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
00314 typedef float_ieee754_double Binary;
00315 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IBM_SINGLE
00316 typedef float_ibm_single Binary;
00317 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_QUAD
00318 typedef float_ieee754_quad Binary;
00319 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_INTEL_DOUBLE_EXTENDED
00320 typedef float_intel_double_extended Binary;
00321 #else
00322 #error "invalid value for PPL_CXX_DOUBLE_BINARY_FORMAT"
00323 #endif
00324 union {
00325 double number;
00326 Binary binary;
00327 } u;
00328 Float();
00329 Float(double v);
00330 double value();
00331 };
00332 #endif
00333
00334 #if PPL_SUPPORTED_LONG_DOUBLE
00335 template <>
00336 class Float<long double> : public True {
00337 public:
00338 #if PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_HALF
00339 typedef float_ieee754_half Binary;
00340 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
00341 typedef float_ieee754_single Binary;
00342 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
00343 typedef float_ieee754_double Binary;
00344 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IBM_SINGLE
00345 typedef float_ibm_single Binary;
00346 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_QUAD
00347 typedef float_ieee754_quad Binary;
00348 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_INTEL_DOUBLE_EXTENDED
00349 typedef float_intel_double_extended Binary;
00350 #else
00351 #error "invalid value for PPL_CXX_LONG_DOUBLE_BINARY_FORMAT"
00352 #endif
00353 union {
00354 long double number;
00355 Binary binary;
00356 } u;
00357 Float();
00358 Float(long double v);
00359 long double value();
00360 };
00361 #endif
00362
00363 }
00364
00365 #include "Float.inlines.hh"
00366
00367 #endif // !defined(PPL_Float_defs_hh)