00001 /* IEC 559 floating point format related functions. 00002 Copyright (C) 2001-2006 Roberto Bagnara <bagnara@cs.unipr.it> 00003 00004 This file is part of the Parma Polyhedra Library (PPL). 00005 00006 The PPL is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU General Public License as published by the 00008 Free Software Foundation; either version 2 of the License, or (at your 00009 option) any later version. 00010 00011 The PPL is distributed in the hope that it will be useful, but WITHOUT 00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00014 for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software Foundation, 00018 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 00019 00020 For the most up-to-date information see the Parma Polyhedra Library 00021 site: http://www.cs.unipr.it/ppl/ . */ 00022 00023 #ifndef PPL_Float_defs_hh 00024 #define PPL_Float_defs_hh 1 00025 00026 #include "compiler.hh" 00027 #include <gmp.h> 00028 #include <cassert> 00029 #include <cmath> 00030 #ifdef HAVE_STDINT_H 00031 #include <stdint.h> 00032 #endif 00033 #ifdef HAVE_INTTYPES_H 00034 #include <inttypes.h> 00035 #endif 00036 00037 #ifndef NAN 00038 #define NAN (HUGE_VAL - HUGE_VAL) 00039 #endif 00040 00041 namespace Parma_Polyhedra_Library { 00042 00043 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00044 00045 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00046 00047 struct float_ieee754_single { 00048 uint32_t word; 00049 static const uint32_t SGN_MASK = 0x80000000; 00050 static const uint32_t EXP_MASK = 0x7f800000; 00051 static const uint32_t POS_INF = 0x7f800000; 00052 static const uint32_t NEG_INF = 0xff800000; 00053 static const uint32_t POS_ZERO = 0x00000000; 00054 static const uint32_t NEG_ZERO = 0x80000000; 00055 static const unsigned int EXPONENT_BITS = 8; 00056 static const unsigned int MANTISSA_BITS = 23; 00057 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1; 00058 static const int EXPONENT_BIAS = EXPONENT_MAX; 00059 static const int EXPONENT_MIN = -EXPONENT_MAX + 1; 00060 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN 00061 - static_cast<int>(MANTISSA_BITS); 00062 int is_inf() const; 00063 int is_nan() const; 00064 int is_zero() const; 00065 int sign_bit() const; 00066 void negate(); 00067 void dec(); 00068 void inc(); 00069 void set_max(bool negative); 00070 void build(bool negative, mpz_t mantissa, int exponent); 00071 }; 00072 00073 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00074 00075 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00076 00077 struct float_ieee754_double { 00078 #ifdef WORDS_BIGENDIAN 00079 uint32_t msp; 00080 uint32_t lsp; 00081 #else 00082 uint32_t lsp; 00083 uint32_t msp; 00084 #endif 00085 static const uint32_t MSP_SGN_MASK = 0x80000000; 00086 static const uint32_t MSP_POS_INF = 0x7ff00000; 00087 static const uint32_t MSP_NEG_INF = 0xfff00000; 00088 static const uint32_t MSP_POS_ZERO = 0x00000000; 00089 static const uint32_t MSP_NEG_ZERO = 0x80000000; 00090 static const uint32_t LSP_INF = 0; 00091 static const uint32_t LSP_ZERO = 0; 00092 static const uint32_t LSP_MAX = 0xffffffff; 00093 static const unsigned int EXPONENT_BITS = 11; 00094 static const unsigned int MANTISSA_BITS = 52; 00095 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1; 00096 static const int EXPONENT_BIAS = EXPONENT_MAX; 00097 static const int EXPONENT_MIN = -EXPONENT_MAX + 1; 00098 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN 00099 - static_cast<int>(MANTISSA_BITS); 00100 int is_inf() const; 00101 int is_nan() const; 00102 int is_zero() const; 00103 int sign_bit() const; 00104 void negate(); 00105 void dec(); 00106 void inc(); 00107 void set_max(bool negative); 00108 void build(bool negative, mpz_t mantissa, int exponent); 00109 }; 00110 00111 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00112 00113 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00114 00115 struct float_intel_double_extended { 00116 #ifdef WORDS_BIGENDIAN 00117 uint32_t msp; 00118 uint64_t lsp; 00119 #else 00120 uint64_t lsp; 00121 uint32_t msp; 00122 #endif 00123 static const uint32_t MSP_SGN_MASK = 0x00008000; 00124 static const uint32_t MSP_POS_INF = 0x00007fff; 00125 static const uint32_t MSP_NEG_INF = 0x0000ffff; 00126 static const uint32_t MSP_POS_ZERO = 0x00000000; 00127 static const uint32_t MSP_NEG_ZERO = 0x00008000; 00128 static const uint64_t LSP_INF = 0x8000000000000000ULL; 00129 static const uint64_t LSP_ZERO = 0; 00130 static const uint64_t LSP_DMAX = 0x7fffffffffffffffULL; 00131 static const uint64_t LSP_NMAX = 0xffffffffffffffffULL; 00132 static const unsigned int EXPONENT_BITS = 15; 00133 static const unsigned int MANTISSA_BITS = 63; 00134 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1; 00135 static const int EXPONENT_BIAS = EXPONENT_MAX; 00136 static const int EXPONENT_MIN = -EXPONENT_MAX + 1; 00137 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN 00138 - static_cast<int>(MANTISSA_BITS); 00139 int is_inf() const; 00140 int is_nan() const; 00141 int is_zero() const; 00142 int sign_bit() const; 00143 void negate(); 00144 void dec(); 00145 void inc(); 00146 void set_max(bool negative); 00147 void build(bool negative, mpz_t mantissa, int exponent); 00148 }; 00149 00150 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00151 00152 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00153 00154 struct float_ieee754_quad { 00155 #ifdef WORDS_BIGENDIAN 00156 uint64_t msp; 00157 uint64_t lsp; 00158 #else 00159 uint64_t lsp; 00160 uint64_t msp; 00161 #endif 00162 static const uint64_t MSP_SGN_MASK = 0x8000000000000000ULL; 00163 static const uint64_t MSP_POS_INF = 0x7fff000000000000ULL; 00164 static const uint64_t MSP_NEG_INF = 0xffff000000000000ULL; 00165 static const uint64_t MSP_POS_ZERO = 0x0000000000000000ULL; 00166 static const uint64_t MSP_NEG_ZERO = 0x8000000000000000ULL; 00167 static const uint64_t LSP_INF = 0; 00168 static const uint64_t LSP_ZERO = 0; 00169 static const uint64_t LSP_MAX = 0xffffffffffffffffULL; 00170 static const unsigned int EXPONENT_BITS = 15; 00171 static const unsigned int MANTISSA_BITS = 112; 00172 static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1; 00173 static const int EXPONENT_BIAS = EXPONENT_MAX; 00174 static const int EXPONENT_MIN = -EXPONENT_MAX + 1; 00175 static const int EXPONENT_MIN_DENORM = EXPONENT_MIN 00176 - static_cast<int>(MANTISSA_BITS); 00177 int is_inf() const; 00178 int is_nan() const; 00179 int is_zero() const; 00180 int sign_bit() const; 00181 void negate(); 00182 void dec(); 00183 void inc(); 00184 void set_max(bool negative); 00185 void build(bool negative, mpz_t mantissa, int exponent); 00186 }; 00187 00188 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00189 00190 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00191 template <typename T> 00192 class Float { 00193 public: 00194 static const bool fpu_related = false; 00195 }; 00196 00197 #if PPL_SUPPORTED_FLOAT 00198 template <> 00199 class Float<float> { 00200 public: 00201 typedef CXX_FLOAT_BINARY_FORMAT Binary; 00202 union { 00203 float number; 00204 Binary binary; 00205 } u; 00206 Float(); 00207 Float(float v); 00208 float value(); 00209 static const bool fpu_related = true; 00210 }; 00211 #endif 00212 00213 #if PPL_SUPPORTED_DOUBLE 00214 template <> 00215 class Float<double> { 00216 public: 00217 typedef CXX_DOUBLE_BINARY_FORMAT Binary; 00218 union { 00219 double number; 00220 Binary binary; 00221 } u; 00222 Float(); 00223 Float(double v); 00224 double value(); 00225 static const bool fpu_related = true; 00226 }; 00227 #endif 00228 00229 #if PPL_SUPPORTED_LONG_DOUBLE 00230 template <> 00231 class Float<long double> { 00232 public: 00233 typedef CXX_LONG_DOUBLE_BINARY_FORMAT Binary; 00234 union { 00235 long double number; 00236 Binary binary; 00237 } u; 00238 Float(); 00239 Float(long double v); 00240 long double value(); 00241 static const bool fpu_related = true; 00242 }; 00243 #endif 00244 00245 } // namespace Parma_Polyhedra_Library 00246 00247 #include "Float.inlines.hh" 00248 00249 #endif // !defined(PPL_Float_defs_hh)