[PPL-devel] [GIT] ppl/ppl(floating_point): Extended float_ieee754_half format.

Fabio Biselli fabio.biselli at studenti.unipr.it
Mon Oct 5 17:10:43 CEST 2009


Module: ppl/ppl
Branch: floating_point
Commit: 8847a837fb858259f80990b984956d8a34689ed7
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=8847a837fb858259f80990b984956d8a34689ed7

Author: Fabio Biselli <fabio.biselli at studenti.unipr.it>
Date:   Mon Oct  5 16:34:35 2009 +0200

Extended float_ieee754_half format.
Fixed a function call in test06 with a possible solution.

---

 src/Float.defs.hh                                  |   35 +++++++++++--
 src/Float.inlines.hh                               |   58 ++++++++++++++++++++
 tests/Floating_Point_Expression/digitalfilters1.cc |   10 ++++
 3 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/src/Float.defs.hh b/src/Float.defs.hh
index 6586e0e..41b9f83 100644
--- a/src/Float.defs.hh
+++ b/src/Float.defs.hh
@@ -42,9 +42,30 @@ namespace Parma_Polyhedra_Library {
 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
 
 struct float_ieee754_half {
+  uint32_t word;
+  static const uint32_t SGN_MASK = 0x8000;
+  static const uint32_t EXP_MASK = 0xfc00;
+  static const uint32_t POS_INF = 0xfc00;
+  static const uint32_t NEG_INF = 0x7c00;
+  static const uint32_t POS_ZERO = 0x0000;
+  static const uint32_t NEG_ZERO = 0x8000;
   static const unsigned int EXPONENT_BITS = 5;
   static const unsigned int MANTISSA_BITS = 10;
-  static const int EXPONENT_BIAS = 15;
+  static const int EXPONENT_MAX = (1 << (EXPONENT_BITS - 1)) - 1;
+  static const int EXPONENT_BIAS = EXPONENT_MAX;
+  static const int EXPONENT_MIN = -EXPONENT_MAX + 1;
+  static const int EXPONENT_MIN_DENORM = EXPONENT_MIN
+					- static_cast<int>(MANTISSA_BITS);
+  int is_inf() const;
+  int is_nan() const;
+  int is_zero() const;
+  int sign_bit() const;
+  void negate();
+  void dec();
+  void inc();
+  void set_max(bool negative);
+  void build(bool negative, mpz_t mantissa, int exponent);
+
 };
 
 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
@@ -228,7 +249,9 @@ class Float : public False { };
 template <>
 class Float<float> : public True {
 public:
-#if PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
+#if PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_HALF
+  typedef float_ieee754_half Binary;
+#elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
   typedef float_ieee754_single Binary;
 #elif PPL_CXX_FLOAT_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
   typedef float_ieee754_double Binary;
@@ -253,7 +276,9 @@ public:
 template <>
 class Float<double> : public True {
 public:
-#if PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
+#if PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_HALF
+  typedef float_ieee754_half Binary;
+#elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
   typedef float_ieee754_single Binary;
 #elif PPL_CXX_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
   typedef float_ieee754_double Binary;
@@ -278,7 +303,9 @@ public:
 template <>
 class Float<long double> : public True {
 public:
-#if PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
+#if PPL_CXX_LONG_BINARY_FORMAT == PPL_FLOAT_IEEE754_HALF
+  typedef float_ieee754_half Binary;
+#elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_SINGLE
   typedef float_ieee754_single Binary;
 #elif PPL_CXX_LONG_DOUBLE_BINARY_FORMAT == PPL_FLOAT_IEEE754_DOUBLE
   typedef float_ieee754_double Binary;
diff --git a/src/Float.inlines.hh b/src/Float.inlines.hh
index 2796f9e..dcbe93f 100644
--- a/src/Float.inlines.hh
+++ b/src/Float.inlines.hh
@@ -26,6 +26,64 @@ site: http://www.cs.unipr.it/ppl/ . */
 #include <climits>
 
 namespace Parma_Polyhedra_Library {
+ 
+inline int
+float_ieee754_half::is_inf() const {
+  if (word == NEG_INF)
+    return -1;
+  if (word == POS_INF)
+    return 1;
+  return 0;
+}
+
+inline int
+float_ieee754_half::is_nan() const {
+  return (word & ~SGN_MASK) > POS_INF;
+}
+
+inline int
+float_ieee754_half::is_zero() const {
+  if (word == NEG_ZERO)
+    return -1;
+  if (word == POS_ZERO)
+    return 1;
+  return 0;
+}
+
+inline void
+float_ieee754_half::negate() {
+  word ^= SGN_MASK;
+}
+
+inline int
+float_ieee754_half::sign_bit() const {
+  return !!(word & SGN_MASK);
+}
+
+inline void
+float_ieee754_half::dec() {
+  --word;
+}
+
+inline void
+float_ieee754_half::inc() {
+  ++word;
+}
+
+inline void
+float_ieee754_half::set_max(bool negative) {
+  word = 0x7bff;
+  if (negative)
+    word |= SGN_MASK;
+}
+
+inline void
+float_ieee754_half::build(bool negative, mpz_t mantissa, int exponent) {
+  word = mpz_get_ui(mantissa) & ((1UL << MANTISSA_BITS) - 1);
+  if (negative)
+    word |= SGN_MASK;
+  word |= static_cast<uint32_t>(exponent + EXPONENT_BIAS) << MANTISSA_BITS;
+}
 
 inline int
 float_ieee754_single::is_inf() const {
diff --git a/tests/Floating_Point_Expression/digitalfilters1.cc b/tests/Floating_Point_Expression/digitalfilters1.cc
index fccd823..3deda9f 100644
--- a/tests/Floating_Point_Expression/digitalfilters1.cc
+++ b/tests/Floating_Point_Expression/digitalfilters1.cc
@@ -596,6 +596,16 @@ test06() {
     assign_r(M, 200, ROUND_DOWN);
     cs.insert(Y <= M);
     cs.insert(Y >= -M);
+    // FIXME: not sound.
+    // ANALYZED_FP_FORMAT max = std::numeric_limits<ANALYZED_FP_FORMAT>::max();
+    // NOTE: std::max() not correct, try use following solution.
+    // ANALYZED_FP_FORMAT max;
+    // max.set_max(false);
+    //PPL_DIRTY_TEMP_COEFFICIENT(M);
+    //assign_r(M, max, ROUND_DOWN);
+    //cs.insert(Y <= M);
+    //cs.insert(Y >= -M);
+    
     ph.limited_BHRZ03_extrapolation_assign(ph_begin, cs);
     Box<FP_Interval> box(ph);
     print_constraints(box, "*** after widening ***");




More information about the PPL-devel mailing list