[Bug 1856] int64x64_t double conversions
authorPeter D. Barnes, Jr. <barnes26@llnl.gov>
Sun, 02 Mar 2014 01:02:23 -0800
changeset 1063767601c471c22
parent 10636 111ac53de0e7
child 10638 aa85c4fcd5d7
[Bug 1856] int64x64_t double conversions
src/core/model/int64x64-128.cc
src/core/model/int64x64-128.h
src/core/model/int64x64-cairo.cc
src/core/model/int64x64-cairo.h
src/core/model/int64x64-double.h
src/core/model/int64x64.cc
src/core/model/int64x64.h
src/core/test/int64x64-test-suite.cc
     1.1 --- a/src/core/model/int64x64-128.cc	Sun Mar 02 00:42:05 2014 -0800
     1.2 +++ b/src/core/model/int64x64-128.cc	Sun Mar 02 01:02:23 2014 -0800
     1.3 @@ -26,16 +26,16 @@
     1.4  }
     1.5  
     1.6  void
     1.7 -int64x64_t::Mul (int64x64_t const &o)
     1.8 +int64x64_t::Mul (const int64x64_t & o)
     1.9  {
    1.10    uint128_t a, b;
    1.11 -  bool sign = output_sign (_v, o._v, a, b);
    1.12 +  bool negative = output_sign (_v, o._v, a, b);
    1.13    uint128_t result = Umul (a, b);
    1.14 -  _v = sign ? -result : result;
    1.15 +  _v = negative ? -result : result;
    1.16  }
    1.17  
    1.18  uint128_t
    1.19 -int64x64_t::Umul (uint128_t a, uint128_t b)
    1.20 +int64x64_t::Umul (const uint128_t a, const uint128_t b)
    1.21  {
    1.22    uint128_t aL = a & HP_MASK_LO;
    1.23    uint128_t bL = b & HP_MASK_LO;
    1.24 @@ -75,16 +75,16 @@
    1.25  }
    1.26  
    1.27  void
    1.28 -int64x64_t::Div (int64x64_t const &o)
    1.29 +int64x64_t::Div (const int64x64_t & o)
    1.30  {
    1.31    uint128_t a, b;
    1.32 -  bool sign = output_sign (_v, o._v, a, b);
    1.33 +  bool negative = output_sign (_v, o._v, a, b);
    1.34    int128_t result = Udiv (a, b);
    1.35 -  _v = sign ? -result : result;
    1.36 +  _v = negative ? -result : result;
    1.37  }
    1.38  
    1.39  uint128_t
    1.40 -int64x64_t::Udiv (uint128_t a, uint128_t b)
    1.41 +int64x64_t::Udiv (const uint128_t a, const uint128_t b)
    1.42  {
    1.43    
    1.44    uint128_t rem = a;
    1.45 @@ -153,7 +153,7 @@
    1.46  }
    1.47  
    1.48  void 
    1.49 -int64x64_t::MulByInvert (const int64x64_t &o)
    1.50 +int64x64_t::MulByInvert (const int64x64_t & o)
    1.51  {
    1.52    bool negResult = _v < 0;
    1.53    uint128_t a = negResult ? -_v : _v;
    1.54 @@ -161,8 +161,9 @@
    1.55  
    1.56    _v = negResult ? -result : result;
    1.57  }
    1.58 +
    1.59  uint128_t
    1.60 -int64x64_t::UmulByInvert (uint128_t a, uint128_t b)
    1.61 +int64x64_t::UmulByInvert (const uint128_t a, const uint128_t b)
    1.62  {
    1.63    uint128_t result, ah, bh, al, bl;
    1.64    uint128_t hi, mid;
    1.65 @@ -176,8 +177,9 @@
    1.66    result = hi + mid;
    1.67    return result;
    1.68  }
    1.69 +
    1.70  int64x64_t 
    1.71 -int64x64_t::Invert (uint64_t v)
    1.72 +int64x64_t::Invert (const uint64_t v)
    1.73  {
    1.74    NS_ASSERT (v > 1);
    1.75    uint128_t a;
     2.1 --- a/src/core/model/int64x64-128.h	Sun Mar 02 00:42:05 2014 -0800
     2.2 +++ b/src/core/model/int64x64-128.h	Sun Mar 02 01:02:23 2014 -0800
     2.3 @@ -14,32 +14,8 @@
     2.4  namespace ns3 {
     2.5  
     2.6  /**
     2.7 - * \ingroup core
     2.8 - * \defgroup highprec High Precision Q64.64
     2.9 - *
    2.10 - * Functions and class for high precision Q64.64 fixed point arithmetic.
    2.11 - */
    2.12 -  
    2.13 -/**
    2.14 - * \ingroup highprec
    2.15 - * High precision numerical type, implementing Q64.64 fixed precision.
    2.16 - *
    2.17 - * A Q64.64 fixed precision number consists of:
    2.18 - *
    2.19 - *   Bits | Function
    2.20 - *   ---- | --------
    2.21 - *     1  | Sign bit
    2.22 - *    63  | Integer portion
    2.23 - *    64  | Fractional portion
    2.24 - *
    2.25 - * All standard arithemetic operations are supported:
    2.26 - *
    2.27 - *   Category    | Operators
    2.28 - *   ----------- | ---------
    2.29 - *   Computation | `+`, `+=`, `-`, `-=`, `*`, `*=`, `/`, `/=`
    2.30 - *   Comparison  | `==`, `!=`, `<`, `<=`, `>`, `>=`
    2.31 - *   Unary       | `+`, `-`, `!`
    2.32 - *
    2.33 + * \internal
    2.34 + * The implementation documented here is based on native 128-bit integers.
    2.35   */
    2.36  class int64x64_t
    2.37  {
    2.38 @@ -72,9 +48,9 @@
    2.39     * we expose the underlying implementation type here.
    2.40     */
    2.41    enum impl_type {
    2.42 -    int128_impl = 0,  //!< Native int128_t implementation.
    2.43 -    cairo_impl  = 1,  //!< cairo wideint implementation
    2.44 -    ld_impl     = 2   //!< long double implementation
    2.45 +    int128_impl,  //!< Native int128_t implementation.
    2.46 +    cairo_impl,   //!< cairo wideint implementation
    2.47 +    ld_impl,      //!< long double implementation
    2.48    };
    2.49  
    2.50    /// Type tag for this implementation.
    2.51 @@ -89,27 +65,38 @@
    2.52     *
    2.53     * \param [in] value floating value to represent
    2.54     */
    2.55 -  inline int64x64_t (double value)
    2.56 +  inline int64x64_t (const double value)
    2.57    {
    2.58 -    bool sign = value < 0;
    2.59 -    value = sign ? -value : value;
    2.60 -    long double hi = std::floor ((long double)value);
    2.61 -    long double fr = value - hi;
    2.62 -    long double lo = fr * HP_MAX_64;
    2.63 -    _v = (uint128_t)hi << 64;
    2.64 -    _v += (uint128_t)lo;
    2.65 -    _v = sign ? -_v : _v;
    2.66 +    const int64x64_t tmp ((long double)value);
    2.67 +    _v = tmp._v;
    2.68    }
    2.69 -  inline int64x64_t (long double value)
    2.70 +  inline int64x64_t (const long double value)
    2.71    {
    2.72 -    bool sign = value < 0;
    2.73 -    value = sign ? -value : value;
    2.74 -    long double hi = std::floor (value);
    2.75 -    long double fr = value - hi;
    2.76 -    long double lo = fr * HP_MAX_64;
    2.77 -    _v = (uint128_t)hi << 64;
    2.78 -    _v += (uint128_t)lo;
    2.79 -    _v = sign ? -_v : _v;
    2.80 +    const bool negative = value < 0;
    2.81 +    const long double v = negative ? -value : value;
    2.82 +
    2.83 +    long double fhi;
    2.84 +    long double flo = std::modf (v, &fhi);
    2.85 +    // Add 0.5 to round, which improves the last count
    2.86 +    // This breaks these tests:
    2.87 +    //   TestSuite devices-mesh-dot11s-regression
    2.88 +    //   TestSuite devices-mesh-flame-regression
    2.89 +    //   TestSuite routing-aodv-regression
    2.90 +    //   TestSuite routing-olsr-regression
    2.91 +    // Setting round = 0; breaks:
    2.92 +    //   TestSuite int64x64
    2.93 +    const long double round = 0.5;
    2.94 +    flo = flo * HP_MAX_64 + round;
    2.95 +    int128_t hi = fhi;
    2.96 +    const uint64_t lo = flo;
    2.97 +    if (flo >= HP_MAX_64)
    2.98 +      {
    2.99 +	// conversion to uint64 rolled over
   2.100 +	++hi;
   2.101 +      }
   2.102 +    _v = hi << 64;
   2.103 +    _v |= lo;
   2.104 +    _v = negative ? -_v : _v;
   2.105    }
   2.106    /**@}*/
   2.107  
   2.108 @@ -119,32 +106,32 @@
   2.109     *
   2.110     * \param [in] v integer value to represent
   2.111     */
   2.112 -  inline int64x64_t (int v)
   2.113 +  inline int64x64_t (const int v)
   2.114      : _v (v)
   2.115    {
   2.116      _v <<= 64;
   2.117    }
   2.118 -  inline int64x64_t (long int v)
   2.119 +  inline int64x64_t (const long int v)
   2.120      : _v (v) 
   2.121    {
   2.122      _v <<= 64;
   2.123    }
   2.124 -  inline int64x64_t (long long int v)
   2.125 +  inline int64x64_t (const long long int v)
   2.126      : _v (v) 
   2.127    {
   2.128      _v <<= 64;
   2.129    }
   2.130 -  inline int64x64_t (unsigned int v)
   2.131 +  inline int64x64_t (const unsigned int v)
   2.132      : _v (v)
   2.133    {
   2.134      _v <<= 64;
   2.135    }
   2.136 -  inline int64x64_t (unsigned long int v)
   2.137 +  inline int64x64_t (const unsigned long int v)
   2.138      : _v (v) 
   2.139    {
   2.140      _v <<= 64;
   2.141    }
   2.142 -  inline int64x64_t (unsigned long long int v)
   2.143 +  inline int64x64_t (const unsigned long long int v)
   2.144      : _v (v) 
   2.145    {
   2.146      _v <<= 64;
   2.147 @@ -156,13 +143,10 @@
   2.148     * \param [in] hi Integer portion.
   2.149     * \param [in] lo Fractional portion, already scaled to HP_MAX_64.
   2.150     */
   2.151 -  explicit inline int64x64_t (int64_t hi, uint64_t lo)
   2.152 +  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
   2.153    {
   2.154 -    bool sign = hi<0;
   2.155 -    _v = sign ? -hi : hi;
   2.156 -    _v <<= 64;
   2.157 -    _v += lo;
   2.158 -    _v = sign ? -_v : _v;
   2.159 +    _v = (int128_t)hi << 64;
   2.160 +    _v |= lo;
   2.161    }
   2.162  
   2.163    /**
   2.164 @@ -190,12 +174,13 @@
   2.165     */
   2.166    inline double GetDouble (void) const
   2.167    {
   2.168 -    bool sign = _v < 0;
   2.169 -    uint128_t value = sign ? -_v : _v;
   2.170 -    long double flo = (value & HP_MASK_LO) / HP_MAX_64;
   2.171 -    long double retval = value >> 64;
   2.172 +    const bool negative = _v < 0;
   2.173 +    const uint128_t value = negative ? -_v : _v;
   2.174 +    const long double fhi = value >> 64;
   2.175 +    const long double flo = (value & HP_MASK_LO) / HP_MAX_64;
   2.176 +    long double retval = fhi;
   2.177      retval += flo;
   2.178 -    retval = sign ? -retval : retval;
   2.179 +    retval = negative ? -retval : retval;
   2.180      return retval;
   2.181    }
   2.182    /**
   2.183 @@ -205,11 +190,8 @@
   2.184     */
   2.185    inline int64_t GetHigh (void) const
   2.186    {
   2.187 -    bool sign = _v < 0;
   2.188 -    int128_t value = sign ? -_v : _v;
   2.189 -    value >>= 64;
   2.190 -    int64_t retval = value;
   2.191 -    return sign ? -retval : retval;
   2.192 +    const int128_t retval = _v >> 64;
   2.193 +    return retval;
   2.194    }
   2.195    /**
   2.196     * Get the fractional portion of this value, unscaled.
   2.197 @@ -218,9 +200,7 @@
   2.198     */
   2.199    inline uint64_t GetLow (void) const
   2.200    {
   2.201 -    bool sign = _v < 0;
   2.202 -    int128_t value = sign ? -_v : _v;
   2.203 -    uint128_t retval = value & HP_MASK_LO;
   2.204 +    const uint128_t retval = _v & HP_MASK_LO;
   2.205      return retval;
   2.206    }
   2.207  
   2.208 @@ -247,15 +227,13 @@
   2.209     * \param [in] v The value to compute the inverse of.
   2.210     * \return A Q0.128 representation of the inverse.
   2.211     */
   2.212 -  static int64x64_t Invert (uint64_t v);
   2.213 +  static int64x64_t Invert (const uint64_t v);
   2.214  
   2.215  private:
   2.216    friend bool         operator == (const int64x64_t & lhs, const int64x64_t & rhs);
   2.217  
   2.218    friend bool         operator <  (const int64x64_t & lhs, const int64x64_t & rhs);
   2.219 -  friend bool         operator <= (const int64x64_t & lhs, const int64x64_t & rhs);
   2.220    friend bool         operator >  (const int64x64_t & lhs, const int64x64_t & rhs);
   2.221 -  friend bool         operator >= (const int64x64_t & lhs, const int64x64_t & rhs);
   2.222    
   2.223    friend int64x64_t & operator += (      int64x64_t & lhs, const int64x64_t & rhs);
   2.224    friend int64x64_t & operator -= (      int64x64_t & lhs, const int64x64_t & rhs);
   2.225 @@ -301,7 +279,7 @@
   2.226     * high and low 64 bits.  To achieve this, we carry out the multiplication
   2.227     * explicitly with 64-bit operands and 128-bit intermediate results.
   2.228     */
   2.229 -  static uint128_t Umul         (uint128_t a, uint128_t b);
   2.230 +  static uint128_t Umul         (const uint128_t a, const uint128_t b);
   2.231    /**
   2.232     * Unsigned division of Q64.64 values.
   2.233     *
   2.234 @@ -309,7 +287,7 @@
   2.235     * \param [in] b Denominator.
   2.236     * \return The Q64.64 representation of `a / b`
   2.237     */
   2.238 -  static uint128_t Udiv         (uint128_t a, uint128_t b);
   2.239 +  static uint128_t Udiv         (const uint128_t a, const uint128_t b);
   2.240    /**
   2.241     * Unsigned multiplication of Q64.64 and Q0.128 values.
   2.242     *
   2.243 @@ -319,14 +297,14 @@
   2.244     *
   2.245     * \see Invert
   2.246     */
   2.247 -  static uint128_t UmulByInvert (uint128_t a, uint128_t b);
   2.248 +  static uint128_t UmulByInvert (const uint128_t a, const uint128_t b);
   2.249  
   2.250    /**
   2.251     * Construct from an integral type.
   2.252     *
   2.253     * \param [in] v integer value to represent
   2.254     */
   2.255 -  inline int64x64_t (int128_t v)
   2.256 +  inline int64x64_t (const int128_t v)
   2.257      : _v (v) {}
   2.258  
   2.259    int128_t _v;  //!< The Q64.64 value.
   2.260 @@ -344,14 +322,6 @@
   2.261  }
   2.262  /**
   2.263   * \ingroup highprec
   2.264 - * Inequality operator
   2.265 - */
   2.266 -inline bool operator != (const int64x64_t & lhs, const int64x64_t & rhs)
   2.267 -{
   2.268 -  return !(lhs == rhs);
   2.269 -}
   2.270 -/**
   2.271 - * \ingroup highprec
   2.272   * Less than operator
   2.273   */
   2.274  inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
   2.275 @@ -360,28 +330,12 @@
   2.276  }
   2.277  /**
   2.278   * \ingroup highprec
   2.279 - * Less or equal operator
   2.280 - */
   2.281 -inline bool operator <= (const int64x64_t & lhs, const int64x64_t & rhs)
   2.282 -{
   2.283 -  return lhs._v <= rhs._v;
   2.284 -}
   2.285 -/**
   2.286 - * \ingroup highprec
   2.287   * Greater operator
   2.288   */
   2.289  inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
   2.290  {
   2.291    return lhs._v > rhs._v;
   2.292  }
   2.293 -/**
   2.294 - * \ingroup highprec
   2.295 - * Greater or equal operator
   2.296 - */
   2.297 -inline bool operator >= (const int64x64_t & lhs, const int64x64_t & rhs)
   2.298 -{
   2.299 -  return lhs._v >= rhs._v;
   2.300 -}
   2.301  
   2.302  /**
   2.303   * \ingroup highprec
     3.1 --- a/src/core/model/int64x64-cairo.cc	Sun Mar 02 00:42:05 2014 -0800
     3.2 +++ b/src/core/model/int64x64-cairo.cc	Sun Mar 02 01:02:23 2014 -0800
     3.3 @@ -56,7 +56,7 @@
     3.4  }
     3.5  
     3.6  void
     3.7 -int64x64_t::Mul (int64x64_t const &o)
     3.8 +int64x64_t::Mul (const int64x64_t & o)
     3.9  {
    3.10    cairo_uint128_t a, b;
    3.11    bool sign = output_sign (_v, o._v, a, b);
    3.12 @@ -65,7 +65,7 @@
    3.13  }
    3.14  
    3.15  cairo_uint128_t
    3.16 -int64x64_t::Umul (cairo_uint128_t a, cairo_uint128_t b)
    3.17 +int64x64_t::Umul (const cairo_uint128_t a, const cairo_uint128_t b)
    3.18  {
    3.19    cairo_uint128_t result;
    3.20    cairo_uint128_t hiPart, loPart, midPart;
    3.21 @@ -101,7 +101,7 @@
    3.22  }
    3.23  
    3.24  void
    3.25 -int64x64_t::Div (int64x64_t const &o)
    3.26 +int64x64_t::Div (const int64x64_t & o)
    3.27  {
    3.28    cairo_uint128_t a, b;
    3.29    bool sign = output_sign (_v, o._v, a, b);
    3.30 @@ -110,7 +110,7 @@
    3.31  }
    3.32  
    3.33  cairo_uint128_t
    3.34 -int64x64_t::Udiv (cairo_uint128_t a, cairo_uint128_t b)
    3.35 +int64x64_t::Udiv (const cairo_uint128_t a, const cairo_uint128_t b)
    3.36  {
    3.37    cairo_uint128_t den = b;
    3.38    cairo_uquorem128_t qr = _cairo_uint128_divrem (a, b);
    3.39 @@ -176,7 +176,7 @@
    3.40  }
    3.41  
    3.42  void 
    3.43 -int64x64_t::MulByInvert (const int64x64_t &o)
    3.44 +int64x64_t::MulByInvert (const int64x64_t & o)
    3.45  {
    3.46    bool sign = _cairo_int128_negative (_v);
    3.47    cairo_uint128_t a = sign ? _cairo_int128_negate (_v) : _v;
    3.48 @@ -184,8 +184,9 @@
    3.49  
    3.50    _v = sign ? _cairo_int128_negate (result) : result;
    3.51  }
    3.52 +  
    3.53  cairo_uint128_t
    3.54 -int64x64_t::UmulByInvert (cairo_uint128_t a, cairo_uint128_t b)
    3.55 +int64x64_t::UmulByInvert (const cairo_uint128_t a, const cairo_uint128_t b)
    3.56  {
    3.57    cairo_uint128_t result;
    3.58    cairo_uint128_t hi, mid;
    3.59 @@ -197,8 +198,9 @@
    3.60    result = _cairo_uint128_add (hi,mid);
    3.61    return result;
    3.62  }
    3.63 +
    3.64  int64x64_t 
    3.65 -int64x64_t::Invert (uint64_t v)
    3.66 +int64x64_t::Invert (const uint64_t v)
    3.67  {
    3.68    NS_ASSERT (v > 1);
    3.69    cairo_uint128_t a, factor;
     4.1 --- a/src/core/model/int64x64-cairo.h	Sun Mar 02 00:42:05 2014 -0800
     4.2 +++ b/src/core/model/int64x64-cairo.h	Sun Mar 02 01:02:23 2014 -0800
     4.3 @@ -10,32 +10,8 @@
     4.4  namespace ns3 {
     4.5  
     4.6  /**
     4.7 - * \ingroup core
     4.8 - * \defgroup highprec High Precision Q64.64
     4.9 - *
    4.10 - * Functions and class for high precision Q64.64 fixed point arithmetic.
    4.11 - */
    4.12 -  
    4.13 -/**
    4.14 - * \ingroup highprec
    4.15 - * High precision numerical type, implementing Q64.64 fixed precision.
    4.16 - *
    4.17 - * A Q64.64 fixed precision number consists of:
    4.18 - *
    4.19 - *   Bits | Function
    4.20 - *   ---- | --------
    4.21 - *     1  | Sign bit
    4.22 - *    63  | Integer portion
    4.23 - *    64  | Fractional portion
    4.24 - *
    4.25 - * All standard arithemetic operations are supported:
    4.26 - *
    4.27 - *   Category    | Operators
    4.28 - *   ----------- | ---------
    4.29 - *   Computation | `+`, `+=`, `-`, `-=`, `*`, `*=`, `/`, `/=`
    4.30 - *   Comparison  | `==`, `!=`, `<`, `<=`, `>`, `>=`
    4.31 - *   Unary       | `+`, `-`, `!`
    4.32 - *
    4.33 + * \internal
    4.34 + * The implementation documented here uses cairo 128-bit integers.
    4.35   */
    4.36  class int64x64_t
    4.37  {
    4.38 @@ -66,9 +42,9 @@
    4.39     * we expose the underlying implementation type here.
    4.40     */
    4.41    enum impl_type {
    4.42 -    int128_impl = 0,  //!< Native int128_t implementation.
    4.43 -    cairo_impl  = 1,  //!< cairo wideint implementation
    4.44 -    ld_impl     = 2   //!< long double implementation
    4.45 +    int128_impl,  //!< Native int128_t implementation.
    4.46 +    cairo_impl,   //!< cairo wideint implementation
    4.47 +    ld_impl,      //!< long double implementation
    4.48    };
    4.49  
    4.50    /// Type tag for this implementation.
    4.51 @@ -86,33 +62,38 @@
    4.52     *
    4.53     * \param [in] value floating value to represent
    4.54     */
    4.55 -  inline int64x64_t (double value)
    4.56 +  inline int64x64_t (const double value)
    4.57    {
    4.58 -    bool sign = value < 0;
    4.59 -    value = sign ? -value : value;
    4.60 -    long double hi = std::floor ((long double)value);
    4.61 -    long double fr = value - hi;
    4.62 -    long double lo = fr * HP_MAX_64;
    4.63 +    const int64x64_t tmp ((long double)value);
    4.64 +    _v = tmp._v;
    4.65 +  }
    4.66 +  inline int64x64_t (const long double value)
    4.67 +  {
    4.68 +    const bool negative = value < 0;
    4.69 +    const long double v = negative ? -value : value;
    4.70 +
    4.71 +    long double fhi;
    4.72 +    long double flo = std::modf (v, &fhi);
    4.73 +    // Add 0.5 to round, which improves the last count
    4.74 +    // This breaks these tests:
    4.75 +    //   TestSuite devices-mesh-dot11s-regression
    4.76 +    //   TestSuite devices-mesh-flame-regression
    4.77 +    //   TestSuite routing-aodv-regression
    4.78 +    //   TestSuite routing-olsr-regression
    4.79 +    // Setting round = 0; breaks:
    4.80 +    //   TestSuite int64x64
    4.81 +    const long double round = 0.5;
    4.82 +    flo = flo * HP_MAX_64 + round;
    4.83 +    cairo_int64_t  hi = fhi;
    4.84 +    const cairo_uint64_t lo = flo;
    4.85 +    if (flo >= HP_MAX_64)
    4.86 +      {
    4.87 +	// conversion to uint64 rolled over
    4.88 +	++hi;
    4.89 +      }
    4.90      _v.hi = hi;
    4.91      _v.lo = lo;
    4.92 -    if (sign)
    4.93 -      {
    4.94 -	Negate ();
    4.95 -      }
    4.96 -  }
    4.97 -  inline int64x64_t (long double value)
    4.98 -  {
    4.99 -    bool sign = value < 0;
   4.100 -    value = sign ? -value : value;
   4.101 -    long double hi = std::floor (value);
   4.102 -    long double fr = value - hi;
   4.103 -    long double lo = fr * HP_MAX_64;
   4.104 -    _v.hi = hi;
   4.105 -    _v.lo = lo;
   4.106 -    if (sign)
   4.107 -      {
   4.108 -	Negate ();
   4.109 -      }
   4.110 +    _v = negative ? _cairo_int128_negate (_v) : _v;
   4.111    }
   4.112    /**@}*/
   4.113  
   4.114 @@ -122,32 +103,32 @@
   4.115     *
   4.116     * \param [in] v integer value to represent
   4.117     */
   4.118 -  inline int64x64_t (int v)
   4.119 +  inline int64x64_t (const int v)
   4.120    {
   4.121      _v.hi = v;
   4.122      _v.lo = 0;
   4.123    }
   4.124 -  inline int64x64_t (long int v)
   4.125 +  inline int64x64_t (const long int v)
   4.126    {
   4.127      _v.hi = v;
   4.128      _v.lo = 0;
   4.129    }
   4.130 -  inline int64x64_t (long long int v)
   4.131 +  inline int64x64_t (const long long int v)
   4.132    {
   4.133      _v.hi = v;
   4.134      _v.lo = 0;
   4.135    }
   4.136 -  inline int64x64_t (unsigned int v)
   4.137 +  inline int64x64_t (const unsigned int v)
   4.138    {
   4.139      _v.hi = v;
   4.140      _v.lo = 0;
   4.141    }
   4.142 -  inline int64x64_t (unsigned long int v)
   4.143 +  inline int64x64_t (const unsigned long int v)
   4.144    {
   4.145      _v.hi = v;
   4.146      _v.lo = 0;
   4.147    }
   4.148 -  inline int64x64_t (unsigned long long int v)
   4.149 +  inline int64x64_t (const unsigned long long int v)
   4.150    {
   4.151      _v.hi = v;
   4.152      _v.lo = 0;
   4.153 @@ -159,7 +140,7 @@
   4.154     * \param [in] hi Integer portion.
   4.155     * \param [in] lo Fractional portion, already scaled to HP_MAX_64.
   4.156     */
   4.157 -  explicit inline int64x64_t (int64_t hi, uint64_t lo)
   4.158 +  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
   4.159    {
   4.160      _v.hi = hi;
   4.161      _v.lo = lo;
   4.162 @@ -190,12 +171,13 @@
   4.163     */
   4.164    inline double GetDouble (void) const
   4.165    {
   4.166 -    bool sign = IsNegative ();
   4.167 -    cairo_int128_t tmp = sign ? _cairo_int128_negate (_v) : _v;
   4.168 -    long double flo = tmp.lo / HP_MAX_64;
   4.169 -    long double retval = tmp.hi;
   4.170 +    const bool negative = _cairo_int128_negative (_v);
   4.171 +    const cairo_int128_t value = negative ? _cairo_int128_negate (_v) : _v;
   4.172 +    const long double fhi = value.hi;
   4.173 +    const long double flo = value.lo / HP_MAX_64;
   4.174 +    long double retval = fhi;
   4.175      retval += flo;
   4.176 -    retval = sign ? -retval : retval;
   4.177 +    retval = negative ? -retval : retval;
   4.178      return retval;
   4.179    }
   4.180    /**
   4.181 @@ -240,15 +222,13 @@
   4.182     * \param [in] v The value to compute the inverse of.
   4.183     * \return A Q0.128 representation of the inverse.
   4.184     */
   4.185 -  static int64x64_t Invert (uint64_t v);
   4.186 +  static int64x64_t Invert (const uint64_t v);
   4.187  
   4.188  private:
   4.189    friend bool         operator == (const int64x64_t & lhs, const int64x64_t & rhs);
   4.190  
   4.191    friend bool         operator <  (const int64x64_t & lhs, const int64x64_t & rhs);
   4.192 -  friend bool         operator <= (const int64x64_t & lhs, const int64x64_t & rhs);
   4.193    friend bool         operator >  (const int64x64_t & lhs, const int64x64_t & rhs);
   4.194 -  friend bool         operator >= (const int64x64_t & lhs, const int64x64_t & rhs);
   4.195    
   4.196    friend int64x64_t & operator += (      int64x64_t & lhs, const int64x64_t & rhs);
   4.197    friend int64x64_t & operator -= (      int64x64_t & lhs, const int64x64_t & rhs);
   4.198 @@ -294,7 +274,7 @@
   4.199     * high and low 64 bits.  To achieve this, we carry out the multiplication
   4.200     * explicitly with 64-bit operands and 128-bit intermediate results.
   4.201     */
   4.202 -  static cairo_uint128_t Umul         (cairo_uint128_t a, cairo_uint128_t b);
   4.203 +  static cairo_uint128_t Umul (const cairo_uint128_t a, const cairo_uint128_t b);
   4.204    /**
   4.205     * Unsigned division of Q64.64 values.
   4.206     *
   4.207 @@ -302,7 +282,7 @@
   4.208     * \param [in] b Denominator.
   4.209     * \return The Q64.64 representation of `a / b`
   4.210     */
   4.211 -  static cairo_uint128_t Udiv         (cairo_uint128_t a, cairo_uint128_t b);
   4.212 +  static cairo_uint128_t Udiv (const cairo_uint128_t a, const cairo_uint128_t b);
   4.213    /**
   4.214     * Unsigned multiplication of Q64.64 and Q0.128 values.
   4.215     *
   4.216 @@ -312,38 +292,7 @@
   4.217     *
   4.218     * \see Invert
   4.219     */
   4.220 -  static cairo_uint128_t UmulByInvert (cairo_uint128_t a, cairo_uint128_t b);
   4.221 -  /** Negative predicate. */
   4.222 -  inline bool IsNegative (void) const
   4.223 -  {
   4.224 -    bool sign = _cairo_int128_negative (_v);;
   4.225 -    return sign;
   4.226 -  }
   4.227 -  /** Logical negation */
   4.228 -  inline void Negate (void)
   4.229 -  {
   4.230 -    _v.lo = ~_v.lo;
   4.231 -    _v.hi = ~_v.hi;
   4.232 -    if (++_v.lo == 0)
   4.233 -      {
   4.234 -        ++_v.hi;
   4.235 -      }
   4.236 -  }
   4.237 -  /**
   4.238 -   * Return tri-valued comparision to another value.
   4.239 -   *
   4.240 -   * \param [in] o The value to compare to.
   4.241 -   * \return -1 if `this < o`, 0 if they are equal, and +1 if `this > o`.
   4.242 -   */
   4.243 -  inline int Compare (const int64x64_t & o) const
   4.244 -  {
   4.245 -    int status;
   4.246 -    int64x64_t tmp = *this;
   4.247 -    tmp -= o;
   4.248 -    status = (((int64_t)(tmp)._v.hi) < 0) ? -1 :
   4.249 -      (((tmp)._v.hi == 0 && (tmp)._v.lo == 0)) ? 0 : 1;
   4.250 -    return status;
   4.251 -  }
   4.252 +  static cairo_uint128_t UmulByInvert (const cairo_uint128_t a, const cairo_uint128_t b);
   4.253  
   4.254    cairo_int128_t _v;  //!< The Q64.64 value.
   4.255  
   4.256 @@ -356,15 +305,7 @@
   4.257   */
   4.258  inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
   4.259  {
   4.260 -  return lhs._v.hi == rhs._v.hi && lhs._v.lo == rhs._v.lo;
   4.261 -}
   4.262 -/**
   4.263 - * \ingroup highprec
   4.264 - * Inequality operator
   4.265 - */
   4.266 -inline bool operator != (const int64x64_t & lhs, const int64x64_t & rhs)
   4.267 -{
   4.268 -  return !(lhs == rhs);
   4.269 +  return _cairo_int128_eq (lhs._v, rhs._v);
   4.270  }
   4.271  /**
   4.272   * \ingroup highprec
   4.273 @@ -372,15 +313,7 @@
   4.274   */
   4.275  inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
   4.276  {
   4.277 -  return lhs.Compare (rhs) < 0;
   4.278 -}
   4.279 -/**
   4.280 - * \ingroup highprec
   4.281 - * Less or equal operator
   4.282 - */
   4.283 -inline bool operator <= (const int64x64_t & lhs, const int64x64_t & rhs)
   4.284 -{
   4.285 -  return lhs.Compare (rhs) <= 0;
   4.286 +  return _cairo_int128_lt (lhs._v, rhs._v);
   4.287  }
   4.288  /**
   4.289   * \ingroup highprec
   4.290 @@ -388,15 +321,7 @@
   4.291   */
   4.292  inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
   4.293  {
   4.294 -  return lhs.Compare (rhs) > 0;
   4.295 -}
   4.296 -/**
   4.297 - * \ingroup highprec
   4.298 - * Greater or equal operator
   4.299 - */
   4.300 -inline bool operator >= (const int64x64_t & lhs, const int64x64_t & rhs)
   4.301 -{
   4.302 -  return lhs.Compare (rhs) >= 0;
   4.303 +  return _cairo_int128_gt (lhs._v, rhs._v);
   4.304  }
   4.305  
   4.306  /**
   4.307 @@ -451,7 +376,7 @@
   4.308  inline int64x64_t operator - (const int64x64_t & lhs)
   4.309  {
   4.310    int64x64_t tmp = lhs;
   4.311 -  tmp.Negate ();
   4.312 +  tmp._v = _cairo_int128_negate (tmp._v);
   4.313    return tmp;
   4.314  }
   4.315  /**
   4.316 @@ -460,7 +385,7 @@
   4.317   */
   4.318  inline int64x64_t operator ! (const int64x64_t & lhs)
   4.319  {
   4.320 -  return (lhs._v.hi == 0 && lhs._v.lo == 0) ? int64x64_t (1, 0) : int64x64_t ();
   4.321 +  return (lhs == int64x64_t ()) ? int64x64_t (1, 0) : int64x64_t ();
   4.322  }
   4.323  
   4.324  
     5.1 --- a/src/core/model/int64x64-double.h	Sun Mar 02 00:42:05 2014 -0800
     5.2 +++ b/src/core/model/int64x64-double.h	Sun Mar 02 01:02:23 2014 -0800
     5.3 @@ -9,32 +9,8 @@
     5.4  namespace ns3 {
     5.5  
     5.6  /**
     5.7 - * \ingroup core
     5.8 - * \defgroup highprec High Precision Q64.64
     5.9 - *
    5.10 - * Functions and class for high precision Q64.64 fixed point arithmetic.
    5.11 - */
    5.12 -  
    5.13 -/**
    5.14 - * \ingroup highprec
    5.15 - * High precision numerical type, implementing Q64.64 fixed precision.
    5.16 - *
    5.17 - * A Q64.64 fixed precision number consists of:
    5.18 - *
    5.19 - *   Bits | Function
    5.20 - *   ---- | --------
    5.21 - *     1  | Sign bit
    5.22 - *    63  | Integer portion
    5.23 - *    64  | Fractional portion
    5.24 - *
    5.25 - * All standard arithemetic operations are supported:
    5.26 - *
    5.27 - *   Category    | Operators
    5.28 - *   ----------- | ---------
    5.29 - *   Computation | `+`, `+=`, `-`, `-=`, `*`, `*=`, `/`, `/=`
    5.30 - *   Comparison  | `==`, `!=`, `<`, `<=`, `>`, `>=`
    5.31 - *   Unary       | `+`, `-`, `!`
    5.32 - *
    5.33 + * \internal
    5.34 + * The implementation documented here uses native long double.
    5.35   */
    5.36  class int64x64_t
    5.37  {
    5.38 @@ -63,9 +39,9 @@
    5.39     * we expose the underlying implementation type here.
    5.40     */
    5.41    enum impl_type {
    5.42 -    int128_impl = 0,  //!< Native int128_t implementation.
    5.43 -    cairo_impl  = 1,  //!< cairo wideint implementation
    5.44 -    ld_impl     = 2   //!< long double implementation
    5.45 +    int128_impl,  //!< Native int128_t implementation.
    5.46 +    cairo_impl,   //!< cairo wideint implementation
    5.47 +    ld_impl,      //!< long double implementation
    5.48    };
    5.49  
    5.50    /// Type tag for this implementation.
    5.51 @@ -113,7 +89,12 @@
    5.52     */
    5.53    explicit inline int64x64_t (int64_t hi, uint64_t lo)
    5.54    {
    5.55 -    _v = (long double)hi + (long double)lo / HP_MAX_64;
    5.56 +    const bool negative = hi < 0;
    5.57 +    const long double fhi = negative ? -hi : hi;
    5.58 +    const long double flo = lo / HP_MAX_64;
    5.59 +    _v = negative ? - fhi : fhi;
    5.60 +    _v += flo;
    5.61 +    // _v = negative ? -_v : _v;
    5.62    }
    5.63  
    5.64    /**
    5.65 @@ -143,6 +124,48 @@
    5.66    {
    5.67      return (double)_v;
    5.68    }
    5.69 +private:
    5.70 +  /**
    5.71 +   * Get the high and low portions of this value.
    5.72 +   *
    5.73 +   * \return a pair of the high and low words
    5.74 +   */
    5.75 +  std::pair<int64_t, uint64_t> GetHighLow (void) const
    5.76 +    {
    5.77 +    const bool negative = _v < 0;
    5.78 +    const long double v = negative ? -_v : _v;
    5.79 +
    5.80 +    long double fhi;
    5.81 +    long double flo = std::modf (v, &fhi);
    5.82 +    // Add 0.5 to round, which improves the last count
    5.83 +    // This breaks these tests:
    5.84 +    //   TestSuite devices-mesh-dot11s-regression
    5.85 +    //   TestSuite devices-mesh-flame-regression
    5.86 +    //   TestSuite routing-aodv-regression
    5.87 +    //   TestSuite routing-olsr-regression
    5.88 +    // Setting round = 0; breaks:
    5.89 +    //   TestSuite int64x64
    5.90 +    const long double round = 0.5;
    5.91 +    flo = flo * HP_MAX_64 + round;
    5.92 +    int64_t  hi = fhi;
    5.93 +    uint64_t lo = flo;
    5.94 +    if (flo >= HP_MAX_64)
    5.95 +      {
    5.96 +	// conversion to uint64 rolled over
    5.97 +	++hi;
    5.98 +      }
    5.99 +    if (negative)
   5.100 +      {
   5.101 +	lo = ~lo;
   5.102 +	hi = ~hi;
   5.103 +	if (++lo == 0)
   5.104 +	  {
   5.105 +	    ++hi;
   5.106 +	  }
   5.107 +      }
   5.108 +    return std::make_pair (hi, lo);
   5.109 +    }
   5.110 +public:
   5.111    /**
   5.112     * Get the integer portion.
   5.113     *
   5.114 @@ -150,8 +173,50 @@
   5.115     */
   5.116    inline int64_t GetHigh (void) const
   5.117    {
   5.118 -    return (int64_t)std::floor (_v);
   5.119 +    return GetHighLow ().first;
   5.120    }
   5.121 +private:
   5.122 +  /**
   5.123 +   * Get the high and low portions of this value.
   5.124 +   *
   5.125 +   * \return a pair of the high and low words
   5.126 +   */
   5.127 +  std::pair<int64_t, uint64_t> GetHighLow (void) const
   5.128 +    {
   5.129 +    const bool negative = _v < 0;
   5.130 +    const long double v = negative ? -_v : _v;
   5.131 +
   5.132 +    long double fhi;
   5.133 +    long double flo = std::modf (v, &fhi);
   5.134 +    // Add 0.5 to round, which improves the last count
   5.135 +    // This breaks these tests:
   5.136 +    //   TestSuite devices-mesh-dot11s-regression
   5.137 +    //   TestSuite devices-mesh-flame-regression
   5.138 +    //   TestSuite routing-aodv-regression
   5.139 +    //   TestSuite routing-olsr-regression
   5.140 +    // Setting round = 0; breaks:
   5.141 +    //   TestSuite int64x64
   5.142 +    const long double round = 0.5;
   5.143 +    flo = flo * HP_MAX_64 + round;
   5.144 +    int64_t  hi = fhi;
   5.145 +    uint64_t lo = flo;
   5.146 +    if (flo >= HP_MAX_64)
   5.147 +      {
   5.148 +	// conversion to uint64 rolled over
   5.149 +	++hi;
   5.150 +      }
   5.151 +    if (negative)
   5.152 +      {
   5.153 +	lo = ~lo;
   5.154 +	hi = ~hi;
   5.155 +	if (++lo == 0)
   5.156 +	  {
   5.157 +	    ++hi;
   5.158 +	  }
   5.159 +      }
   5.160 +    return std::make_pair (hi, lo);
   5.161 +    }
   5.162 +public:
   5.163    /**
   5.164     * Get the fractional portion of this value, unscaled.
   5.165     *
   5.166 @@ -159,10 +224,7 @@
   5.167     */
   5.168    inline uint64_t GetLow (void) const
   5.169    {
   5.170 -    long double frac = _v - std::floor (_v);
   5.171 -    frac = frac * HP_MASK_LO + 0.5L;
   5.172 -    uint64_t low = (uint64_t)frac;
   5.173 -    return low;
   5.174 +    return GetHighLow ().second;
   5.175    }
   5.176  
   5.177    /**
   5.178 @@ -195,9 +257,7 @@
   5.179    friend bool         operator == (const int64x64_t & lhs, const int64x64_t & rhs);
   5.180  
   5.181    friend bool         operator <  (const int64x64_t & lhs, const int64x64_t & rhs);
   5.182 -  friend bool         operator <= (const int64x64_t & lhs, const int64x64_t & rhs);
   5.183    friend bool         operator >  (const int64x64_t & lhs, const int64x64_t & rhs);
   5.184 -  friend bool         operator >= (const int64x64_t & lhs, const int64x64_t & rhs);
   5.185    
   5.186    friend int64x64_t & operator += (      int64x64_t & lhs, const int64x64_t & rhs);
   5.187    friend int64x64_t & operator -= (      int64x64_t & lhs, const int64x64_t & rhs);
   5.188 @@ -222,14 +282,6 @@
   5.189  }
   5.190  /**
   5.191   * \ingroup highprec
   5.192 - * Inequality operator
   5.193 - */
   5.194 -inline bool operator != (const int64x64_t & lhs, const int64x64_t & rhs)
   5.195 -{
   5.196 -  return !(lhs == rhs);
   5.197 -}
   5.198 -/**
   5.199 - * \ingroup highprec
   5.200   * Less than operator
   5.201   */
   5.202  inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
   5.203 @@ -238,28 +290,12 @@
   5.204  }
   5.205  /**
   5.206   * \ingroup highprec
   5.207 - * Less or equal operator
   5.208 - */
   5.209 -inline bool operator <= (const int64x64_t & lhs, const int64x64_t & rhs)
   5.210 -{
   5.211 -  return lhs._v <= rhs._v;
   5.212 -}
   5.213 -/**
   5.214 - * \ingroup highprec
   5.215   * Greater operator
   5.216   */
   5.217  inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
   5.218  {
   5.219    return lhs._v > rhs._v;
   5.220  }
   5.221 -/**
   5.222 - * \ingroup highprec
   5.223 - * Greater or equal operator
   5.224 - */
   5.225 -inline bool operator >= (const int64x64_t & lhs, const int64x64_t & rhs)
   5.226 -{
   5.227 -  return lhs._v >= rhs._v;
   5.228 -}
   5.229  
   5.230  /**
   5.231   * \ingroup highprec
     6.1 --- a/src/core/model/int64x64.cc	Sun Mar 02 00:42:05 2014 -0800
     6.2 +++ b/src/core/model/int64x64.cc	Sun Mar 02 01:02:23 2014 -0800
     6.3 @@ -14,33 +14,40 @@
     6.4  
     6.5  namespace ns3 {
     6.6  
     6.7 +/**
     6.8 + * \internal
     6.9 + * This algorithm is exact to the precision requested, up to the full
    6.10 + * 64 decimal digits required to exactly represent a 64-bit fraction.
    6.11 + *
    6.12 + * Proper rounding turns out to be surprisingly hard.
    6.13 + * In `y.xxxx5|6`, where the `|` marks follows the last output digit,
    6.14 + * rounding the `5|6` to `6|` is straightforward.  However,
    6.15 + * rounding `y.xxx99|6` should result in `y.xx100|`.  Notice the
    6.16 + * effect of rounding percolates to higher digits.
    6.17 + * We accumulate the output digits in a string, then carry out
    6.18 + * the rounding in the string directly.
    6.19 + */
    6.20  std::ostream &operator << (std::ostream &os, const int64x64_t &value)
    6.21  {
    6.22 -  int64_t hi = value.GetHigh ();
    6.23 +  const bool negative = (value < 0);
    6.24 +  const int64x64_t absVal = (negative ? -value : value);
    6.25 +  
    6.26 +  int64_t hi = absVal.GetHigh ();
    6.27  
    6.28    // Save stream format flags
    6.29 +  const std::streamsize precision = os.precision ();
    6.30    std::ios_base::fmtflags ff = os.flags ();
    6.31 -  os << std::setw (1);
    6.32 +  const bool floatfield = os.flags () & std::ios_base::floatfield;
    6.33 +  os << std::setw (1) << std::noshowpos;
    6.34 +  
    6.35 +  os << std::right << (negative ? "-" : "+");
    6.36  
    6.37 -  { /// \internal
    6.38 -    /// See \bugid{1737}:  gcc libstc++ 4.2 bug
    6.39 -    if (hi == 0)
    6.40 -      { 
    6.41 -	os << '+';
    6.42 -      }
    6.43 -    else
    6.44 -      {
    6.45 -	os << std::showpos;
    6.46 -      }
    6.47 -  }
    6.48 -  
    6.49 -  os << std::right << hi << ".";
    6.50 +  std::ostringstream oss;
    6.51 +  oss << hi << ".";  // collect the digits here so we can round properly
    6.52  
    6.53 -  os << std::noshowpos;
    6.54  
    6.55 -  int64x64_t low(0, value.GetLow ());
    6.56 +  int64x64_t low(0, absVal.GetLow ());
    6.57    int places = 0;    // Number of decimal places printed so far
    6.58 -  const bool floatfield = os.flags () & std::ios_base::floatfield;
    6.59    bool more = true;  // Should we print more digits?
    6.60  
    6.61  #define HEXHILOW(hi, lo) \
    6.62 @@ -51,25 +58,28 @@
    6.63  
    6.64    
    6.65    NS_LOG_LOGIC (std::endl
    6.66 -		<< "  [.] " << " " << HEXHILOW (hi, low.GetLow ()) 
    6.67 -		<< ": " << hi << ".");
    6.68 +		<< (floatfield ? " f" : "  ")
    6.69 +		<< "[" << precision << "] " << hi << ". "
    6.70 +		<< HEXHILOW (hi, low.GetLow ())
    6.71 +		);
    6.72  
    6.73 +  int64_t digit;
    6.74    do 
    6.75      {
    6.76        low *= 10;
    6.77 -      int64_t digit = low.GetHigh ();
    6.78 +      digit = low.GetHigh ();
    6.79        NS_ASSERT_MSG ( (0 <= digit) && (digit <= 9),
    6.80  		      "digit " << digit << " out of range [0,9] "
    6.81  		      << " streaming out "
    6.82  		      << HEXHILOW (value.GetHigh (), value.GetLow ()) );
    6.83        low -= digit;
    6.84  
    6.85 -      os << std::setw (1) << digit;
    6.86 +      oss << std::setw (1) << digit;
    6.87  
    6.88        ++places;
    6.89        if (floatfield)
    6.90  	{
    6.91 -	  more = places < os.precision ();
    6.92 +	  more = places < precision;
    6.93  	}
    6.94        else  // default
    6.95  	{
    6.96 @@ -81,10 +91,46 @@
    6.97  		    << (floatfield ? "f" : " ")
    6.98  		    << "[" << places << "] " << digit
    6.99  		    << HEXHILOW (low.GetHigh (), low.GetLow ())
   6.100 -		    << std::dec << std::setfill (' ' ) << std::left << ")" );
   6.101 +		    << std::dec << std::setfill (' ' ) << std::left);
   6.102  
   6.103      } while (more);
   6.104  
   6.105 +  // Check if we need to round the last printed digit,
   6.106 +  // based on the first unprinted digit
   6.107 +  std::string digits = oss.str ();
   6.108 +  low *= 10;
   6.109 +  int64_t nextDigit = low.GetHigh ();
   6.110 +  if ( (nextDigit > 5) || ((nextDigit == 5) && (digit % 2 == 1)) )
   6.111 +    {
   6.112 +      // Walk backwards with the carry
   6.113 +      bool carry = true;
   6.114 +      for (std::string::reverse_iterator rit = digits.rbegin ();
   6.115 +	   rit != digits.rend ();
   6.116 +	   ++rit)
   6.117 +	{
   6.118 +	  if (*rit == '.')  // Skip over the decimal point
   6.119 +	    {
   6.120 +	      continue ;
   6.121 +	    }
   6.122 +	  
   6.123 +	  ++(*rit);         // Add the carry
   6.124 +	  if (*rit <= '9')  // Relies on character order...
   6.125 +	    {
   6.126 +	      carry = false;
   6.127 +	      break ;       // Carry complete
   6.128 +	    }
   6.129 +	  else
   6.130 +	    {
   6.131 +	      *rit = '0';     // Continue carry to next higher digit
   6.132 +	    }
   6.133 +	}
   6.134 +      if (carry)            // If we still have a carry...
   6.135 +	{
   6.136 +	  digits.insert (digits.begin (), '1');
   6.137 +	}
   6.138 +    }
   6.139 +  os << digits;
   6.140 +  
   6.141    os.flags (ff);  // Restore stream flags
   6.142    return os;
   6.143  }
   6.144 @@ -96,7 +142,7 @@
   6.145    while (*buf != 0)
   6.146      {
   6.147        retval *= 10;
   6.148 -      retval += *buf - 0x30;
   6.149 +      retval += *buf - '0';
   6.150        buf++;
   6.151      }
   6.152    return retval;
   6.153 @@ -104,14 +150,14 @@
   6.154  
   6.155  static uint64_t ReadLoDigits (std::string str)
   6.156  {
   6.157 -  int64x64_t low (0, 0);
   6.158 -  const int64x64_t round (0, 5);
   6.159 +  int64x64_t low;
   6.160 +  const int64x64_t round (0, 5);  // Round last place in division
   6.161  
   6.162 -  for (std::string::const_reverse_iterator rchar = str.rbegin ();
   6.163 -       rchar != str.rend ();
   6.164 -       ++rchar)
   6.165 +  for (std::string::const_reverse_iterator rit = str.rbegin ();
   6.166 +       rit != str.rend ();
   6.167 +       ++rit)
   6.168      {
   6.169 -      int digit = *rchar - '0';
   6.170 +      int digit = *rit - '0';
   6.171        NS_ASSERT_MSG ( (0 <= digit) && (digit <= 9),
   6.172  		      "digit " << digit << " out of range [0,9]"
   6.173  		      << " streaming in low digits \"" << str << "\"");
   6.174 @@ -160,13 +206,20 @@
   6.175        hi = ReadHiDigits (str.substr (cur, next-cur));
   6.176        lo = ReadLoDigits (str.substr (next+1, str.size ()-(next+1)));
   6.177      }
   6.178 -  else
   6.179 +  else if (cur != std::string::npos)
   6.180      {
   6.181        hi = ReadHiDigits (str.substr (cur, str.size ()-cur));
   6.182        lo = 0;
   6.183      }
   6.184 -  hi = negative ? -hi : hi;
   6.185 +  else
   6.186 +    {
   6.187 +      hi = 0;
   6.188 +      lo = 0;
   6.189 +    }
   6.190 +  
   6.191    value = int64x64_t (hi, lo);
   6.192 +  value = negative ? -value : value;
   6.193 +
   6.194    return is;
   6.195  }
   6.196  
     7.1 --- a/src/core/model/int64x64.h	Sun Mar 02 00:42:05 2014 -0800
     7.2 +++ b/src/core/model/int64x64.h	Sun Mar 02 01:02:23 2014 -0800
     7.3 @@ -20,6 +20,74 @@
     7.4  namespace ns3 {
     7.5  
     7.6  /**
     7.7 + * \ingroup core
     7.8 + * \defgroup highprec High Precision Q64.64
     7.9 + *
    7.10 + * Functions and class for high precision Q64.64 fixed point arithmetic.
    7.11 + */
    7.12 +  
    7.13 +/**
    7.14 + * \ingroup highprec
    7.15 + * \class int64x64_t
    7.16 + * 
    7.17 + * High precision numerical type, implementing Q64.64 fixed precision.
    7.18 + *
    7.19 + * A Q64.64 fixed precision number consists of:
    7.20 + *
    7.21 + *   Bits | Function
    7.22 + *   ---- | --------
    7.23 + *     1  | Sign bit
    7.24 + *    63  | Integer portion
    7.25 + *    64  | Fractional portion
    7.26 + *
    7.27 + * The `high` word consists of the sign bit and integer value;
    7.28 + * the `low` word is the fractional part, unscaled.
    7.29 + *
    7.30 + * All standard arithmetic operations are supported:
    7.31 + *
    7.32 + *   Category    | Operators
    7.33 + *   ----------- | ---------
    7.34 + *   Computation | `+`, `+=`, `-`, `-=`, `*`, `*=`, `/`, `/=`
    7.35 + *   Comparison  | `==`, `!=`, `<`, `<=`, `>`, `>=`
    7.36 + *   Unary       | `+`, `-`, `!`
    7.37 + */
    7.38 +
    7.39 +
    7.40 +/**
    7.41 + * \ingroup core
    7.42 + * \defgroup highprec High Precision Q64.64
    7.43 + *
    7.44 + * Functions and class for high precision Q64.64 fixed point arithmetic.
    7.45 + */
    7.46 +  
    7.47 +/**
    7.48 + * \ingroup highprec
    7.49 + * \class int64x64_t
    7.50 + * 
    7.51 + * High precision numerical type, implementing Q64.64 fixed precision.
    7.52 + *
    7.53 + * A Q64.64 fixed precision number consists of:
    7.54 + *
    7.55 + *   Bits | Function
    7.56 + *   ---- | --------
    7.57 + *     1  | Sign bit
    7.58 + *    63  | Integer portion
    7.59 + *    64  | Fractional portion
    7.60 + *
    7.61 + * The `high` word consists of the sign bit and integer value;
    7.62 + * the `low` word is the fractional part, unscaled.
    7.63 + *
    7.64 + * All standard arithmetic operations are supported:
    7.65 + *
    7.66 + *   Category    | Operators
    7.67 + *   ----------- | ---------
    7.68 + *   Computation | `+`, `+=`, `-`, `-=`, `*`, `*=`, `/`, `/=`
    7.69 + *   Comparison  | `==`, `!=`, `<`, `<=`, `>`, `>=`
    7.70 + *   Unary       | `+`, `-`, `!`
    7.71 + */
    7.72 +
    7.73 +
    7.74 +/**
    7.75   * \ingroup highprec
    7.76   * Addition operator.
    7.77   */
    7.78 @@ -63,7 +131,30 @@
    7.79    tmp /= rhs;
    7.80    return tmp;
    7.81  }
    7.82 -
    7.83 +/**
    7.84 + * \ingroup highprec
    7.85 + * Inequality operator
    7.86 + */
    7.87 +inline bool operator != (const int64x64_t & lhs, const int64x64_t & rhs)
    7.88 +{
    7.89 +  return !(lhs == rhs);
    7.90 +}
    7.91 +/**
    7.92 + * \ingroup highprec
    7.93 + * Less or equal operator
    7.94 + */
    7.95 +inline bool operator <= (const int64x64_t & lhs, const int64x64_t & rhs)
    7.96 +{
    7.97 +  return !(lhs > rhs);
    7.98 +}
    7.99 +/**
   7.100 + * \ingroup highprec
   7.101 + * Greater or equal operator
   7.102 + */
   7.103 +inline bool operator >= (const int64x64_t & lhs, const int64x64_t & rhs)
   7.104 +{
   7.105 +  return !(lhs < rhs);
   7.106 +}
   7.107  /**
   7.108   * \ingroup highprec
   7.109   * Output streamer for int64x64_t
     8.1 --- a/src/core/test/int64x64-test-suite.cc	Sun Mar 02 00:42:05 2014 -0800
     8.2 +++ b/src/core/test/int64x64-test-suite.cc	Sun Mar 02 01:02:23 2014 -0800
     8.3 @@ -1,15 +1,26 @@
     8.4  #include "ns3/int64x64.h"
     8.5  #include "ns3/test.h"
     8.6  
     8.7 +#include <cmath>    // fabs
     8.8  #include <iomanip>
     8.9 +#include <limits>   // numeric_limits<>::epsilon ()
    8.10  
    8.11  using namespace ns3;
    8.12  
    8.13 +namespace ns3 {
    8.14 +
    8.15 +  namespace int64x64 {
    8.16 +
    8.17 +    namespace test {
    8.18 +  
    8.19  /**
    8.20 + * \class ns3::int64x64::Int64x64TestSuite
    8.21   * \internal
    8.22   *
    8.23   * Some of these tests are a little unusual for ns-3 in that they
    8.24 - * are sensitive to implementation, specifically the double implementation.
    8.25 + * are sensitive to implementation, specifically the resolution
    8.26 + * of the double and long double implementations.
    8.27 + * 
    8.28   * To handle this, where needed we define a tolerance to use in the
    8.29   * test comparisions.  If you need to increase the tolerance,
    8.30   * please append the system and compiler version.  For example:
    8.31 @@ -21,60 +32,118 @@
    8.32   *   tolerance = 3;
    8.33   * \endcode
    8.34   */
    8.35 +
    8.36 +
    8.37 +class Printer
    8.38 +{
    8.39 +public:
    8.40 +  Printer (const int64_t high, const uint64_t low)
    8.41 +    : m_haveInt (false),
    8.42 +      m_value (0),
    8.43 +      m_high (high),
    8.44 +      m_low (low)
    8.45 +  { }
    8.46 +
    8.47 +  Printer (const int64x64_t value)
    8.48 +    : m_haveInt (true),
    8.49 +      m_value (value),
    8.50 +      m_high (value.GetHigh ()),
    8.51 +      m_low (value.GetLow ())
    8.52 +  { }
    8.53 +
    8.54 +private:
    8.55 +  friend std::ostream & operator << (std::ostream & os, const Printer & p);
    8.56 +
    8.57 +  bool       m_haveInt;
    8.58 +  int64x64_t m_value;
    8.59 +  int64_t    m_high;
    8.60 +  uint64_t   m_low;
    8.61 +};
    8.62 +
    8.63 +std::ostream & operator << (std::ostream & os, const Printer & p)
    8.64 +{
    8.65 +  if (p.m_haveInt)
    8.66 +    {
    8.67 +      os << std::fixed << std::setprecision (22)
    8.68 +	 << p.m_value;
    8.69 +
    8.70 +    }
    8.71 +  
    8.72 +  os << std::hex  << std::setfill ('0')
    8.73 +     << " (0x" << std::setw (16) << p.m_high
    8.74 +     << " 0x"  << std::setw (16) << p.m_low  << ")"
    8.75 +     << std::dec  << std::setfill (' ');
    8.76 +  return os;
    8.77 +}
    8.78 +
    8.79 +	      
    8.80  class Int64x64HiLoTestCase : public TestCase
    8.81  {
    8.82  public:
    8.83    Int64x64HiLoTestCase ();
    8.84    virtual void DoRun (void);
    8.85 -  void Check (const int64_t hi, const uint64_t lo,
    8.86 -	      const int64_t loTolerance = 0);
    8.87 +  void Check (const int64_t hi, const uint64_t lo);
    8.88  };
    8.89  
    8.90 -void 
    8.91 -Int64x64HiLoTestCase::Check (const int64_t hi,
    8.92 -			     const uint64_t lo,
    8.93 -			     const int64_t loTolerance /* = 0 */)
    8.94 -{
    8.95 -  int64x64_t tmp = int64x64_t (hi,lo);
    8.96 -
    8.97 -  std::cout << GetParent ()->GetName () << " Check "
    8.98 -	    << std::hex  << std::setfill ('0')
    8.99 -	    << "hi: 0x"  << std::setw (16) << hi
   8.100 -	    << " lo: 0x" << std::setw (16) << lo
   8.101 -	    << std::dec  << std::setfill (' ')
   8.102 -	    << " int64x64: " << tmp
   8.103 -	    << std::endl;
   8.104 -
   8.105 -  NS_TEST_EXPECT_MSG_EQ (tmp.GetHigh (), hi,
   8.106 -			 "High part does not match for hi:" << hi
   8.107 -			 << " lo: " << lo);
   8.108 -  NS_TEST_EXPECT_MSG_EQ_TOL ((int64_t)tmp.GetLow (), (int64_t)lo, loTolerance,
   8.109 -			     "Low part does not match for hi: " << hi
   8.110 -			     << " lo: " << lo);
   8.111 -}
   8.112 -
   8.113  Int64x64HiLoTestCase::Int64x64HiLoTestCase ()
   8.114    : TestCase ("Manipulate the high and low part of every number")
   8.115  {
   8.116  }
   8.117 -void
   8.118 -Int64x64HiLoTestCase::DoRun (void)
   8.119 +
   8.120 +void 
   8.121 +Int64x64HiLoTestCase::Check (const int64_t hi, const uint64_t lo)
   8.122  {
   8.123 -  std::cout << std::endl;
   8.124 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.125 -	    << std::endl;
   8.126 -
   8.127 -  int64_t tolerance = 0;
   8.128 +  uint64_t tolerance = 0;
   8.129    if (int64x64_t::implementation == int64x64_t::ld_impl)
   8.130      {
   8.131        // Darwin 12.5.0 (Mac 10.8.5) g++ 4.2.1
   8.132        tolerance = 1;
   8.133      }
   8.134 -      
   8.135 -  Check (1,  0);
   8.136 -  Check (1,  1, tolerance);
   8.137 +
   8.138 +  int64x64_t value = int64x64_t (hi,lo);
   8.139 +  uint64_t vLow = value.GetLow ();
   8.140 +  bool pass = ( (value.GetHigh () == hi)
   8.141 +		&& ( (Max (vLow, lo) - Min (vLow, lo)) <= tolerance)
   8.142 +		);
   8.143 +
   8.144 +  std::cout << GetParent ()->GetName () << " Check: "
   8.145 +	    << (pass ? "pass " : "FAIL ")
   8.146 +	    << Printer (value) << " from" << Printer (hi, lo)
   8.147 +	    << std::endl;
   8.148 +
   8.149 +  NS_TEST_EXPECT_MSG_EQ (value.GetHigh (), hi,
   8.150 +			 "High part does not match for hi:" << hi
   8.151 +			 << " lo: " << lo);
   8.152 +  NS_TEST_EXPECT_MSG_EQ_TOL ((int64_t)vLow, (int64_t)lo, (int64_t)tolerance,
   8.153 +			     "Low part does not match for hi: " << hi
   8.154 +			     << " lo: " << lo);
   8.155 +}
   8.156 +
   8.157 +void
   8.158 +Int64x64HiLoTestCase::DoRun (void)
   8.159 +{
   8.160 +  std::cout << std::endl;
   8.161 +  std::cout << GetParent ()->GetName () << " Check: " << GetName ()
   8.162 +	    << std::endl;
   8.163 +
   8.164 +  uint64_t low = 1;
   8.165 +  if (int64x64_t::implementation == int64x64_t::ld_impl)
   8.166 +    {
   8.167 +      // Darwin 12.5.0 (Mac 10.8.5) g++ 4.2.1
   8.168 +      low = 2 * HP_MAX_64 * std::numeric_limits<long double>::epsilon ();
   8.169 +    }
   8.170 +
   8.171 +  Check ( 0, 0);
   8.172 +  Check ( 0, low);
   8.173 +  Check ( 0, 0xffffffffffffffffULL - low);
   8.174 +  
   8.175 +  Check ( 1, 0);
   8.176 +  Check ( 1, low);
   8.177 +  Check ( 1, 0xffffffffffffffffULL - low);
   8.178 +  
   8.179    Check (-1, 0);
   8.180 -  Check (-1, 1);
   8.181 +  Check (-1, low);
   8.182 +  Check (-1, 0xffffffffffffffffULL - low);
   8.183  }
   8.184  
   8.185  
   8.186 @@ -85,7 +154,7 @@
   8.187    virtual void DoRun (void);
   8.188    void Check (const std::string & str,
   8.189  	      const int64_t hi, const uint64_t lo,
   8.190 -	      const int64_t loTolerance = 0);
   8.191 +	      const int64_t tolerance = 0);
   8.192  };
   8.193  Int64x64InputTestCase::Int64x64InputTestCase ()
   8.194    : TestCase ("Parse int64x64_t numbers as strings")
   8.195 @@ -94,29 +163,31 @@
   8.196  void 
   8.197  Int64x64InputTestCase::Check (const std::string & str,
   8.198  			      const int64_t hi, const uint64_t lo,
   8.199 -			      const int64_t loTolerance /* = 0 */)
   8.200 +			      const int64_t tolerance /* = 0 */)
   8.201  			      
   8.202  {
   8.203    std::istringstream iss;
   8.204    iss.str (str);
   8.205 -  int64x64_t hp;
   8.206 -  iss >> hp;
   8.207 +  int64x64_t value;
   8.208 +  iss >> value;
   8.209  
   8.210    std::string input = "\"" + str + "\"";
   8.211 +  uint64_t vLow = value.GetLow ();
   8.212 +  bool pass = ( (value.GetHigh () == hi) &&
   8.213 +		( Max (vLow, lo) - Min (vLow, lo) <= tolerance)
   8.214 +		);
   8.215  
   8.216    std::cout << GetParent ()->GetName () << " Input: "
   8.217 +	    << (pass ? "pass " : "FAIL ")
   8.218  	    << std::left << std::setw (28) << input << std::right
   8.219 -	    << std::hex  << std::setfill ('0')
   8.220 -	    << " hi: 0x" << std::setw (16) << hp.GetHigh ()
   8.221 -	    << " lo: 0x" << std::setw (16) << hp.GetLow ()
   8.222 -	    << std::dec  << std::setfill (' ')
   8.223 -	    << " expected: " << hi << " " << lo << " +/- " << loTolerance
   8.224 +	    << Printer (value) 
   8.225 +	    << " expected: " << Printer (hi, lo) << " +/- " << tolerance
   8.226  	    << std::endl;
   8.227  
   8.228 -  NS_TEST_EXPECT_MSG_EQ (hp.GetHigh (), hi,
   8.229 +  NS_TEST_EXPECT_MSG_EQ (value.GetHigh (), hi,
   8.230  			 "High parts do not match for input string \""
   8.231  			 << str << "\"");
   8.232 -  NS_TEST_EXPECT_MSG_EQ_TOL ((int64_t)hp.GetLow (), (int64_t)lo, loTolerance,
   8.233 +  NS_TEST_EXPECT_MSG_EQ_TOL ((int64_t)value.GetLow (), (int64_t)lo, tolerance,
   8.234  			     "Low parts do not match for input string \""
   8.235  			     << str << "\"");
   8.236  }
   8.237 @@ -124,7 +195,7 @@
   8.238  Int64x64InputTestCase::DoRun (void)
   8.239  {
   8.240    std::cout << std::endl;
   8.241 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.242 +  std::cout << GetParent ()->GetName () << " Input: " << GetName ()
   8.243  	    << std::endl;
   8.244  
   8.245    int64_t tolerance = 0;
   8.246 @@ -147,9 +218,10 @@
   8.247    Check ("-1.0", -1, 0, tolerance);
   8.248    Check ("-1.0000", -1, 0, tolerance);
   8.249    Check (" 1.000000000000000000054",  1, 1, tolerance);
   8.250 -  Check ("-1.000000000000000000054", -1, 1, tolerance);
   8.251 +  Check ("-1.000000000000000000054", -2, -1, tolerance);
   8.252  }
   8.253  
   8.254 +
   8.255  class Int64x64InputOutputTestCase : public TestCase
   8.256  {
   8.257  public:
   8.258 @@ -166,36 +238,52 @@
   8.259  Int64x64InputOutputTestCase::Check (const std::string & str,
   8.260  				    const int64_t tolerance /* = 0 */)
   8.261  {
   8.262 -  std::istringstream iss;
   8.263 -  iss.str (str);
   8.264 +  std::stringstream iss (str);
   8.265 +  int64x64_t expect;
   8.266 +  iss >> expect;
   8.267 +
   8.268 +  std::stringstream oss;
   8.269 +  oss << std::scientific << std::setprecision (21) << expect;
   8.270    int64x64_t value;
   8.271 -  iss >> value;
   8.272 -  std::ostringstream oss;
   8.273 -  oss << std::scientific << std::setprecision (21) << value;
   8.274 +  oss >> value;
   8.275 +
   8.276 +  bool pass = Abs (value - expect) <= int64x64_t (0, tolerance + 1);
   8.277  
   8.278    std::string input  = "\"" + str + "\"";
   8.279    std::string output = "\"" + oss.str () + "\"";
   8.280  
   8.281 -  std::cout << GetParent ()->GetName () << " InputOutput: "
   8.282 -	    << " in: "  << std::left << std::setw (28) << input  << std::right
   8.283 -	    << " out: " << std::left << std::setw (28) << output << std::right
   8.284 -	    << std::endl;
   8.285 -
   8.286 -  if (tolerance == 0)
   8.287 +  if (pass)
   8.288      {
   8.289 -      NS_TEST_EXPECT_MSG_EQ (oss.str (), str,
   8.290 -			     "Converted string does not match expected string");
   8.291 +      std::cout << GetParent ()->GetName () << " InputOutput: "
   8.292 +		<< (pass ? "pass " : "FAIL ")
   8.293 +		<< " in:  " << std::left << std::setw (28) << input
   8.294 +		<< " out: " << std::left << std::setw (28) << output
   8.295 +		<< std::right
   8.296 +		<< std::endl;
   8.297      }
   8.298    else
   8.299      {
   8.300 -      // No obvious way to implement a tolerance
   8.301 -    }
   8.302 +      std::cout << GetParent ()->GetName () << " InputOutput: "
   8.303 +		<< (pass ? "pass " : "FAIL ")
   8.304 +		<< " in:  " << std::left << std::setw (28) << input
   8.305 +		<< std::right << Printer (expect)
   8.306 +		<< std::endl;
   8.307 +      std::cout << GetParent ()->GetName ()
   8.308 +		<< std::setw (19) << " "
   8.309 +		<< " out: " << std::left << std::setw (28) << output
   8.310 +		<< std::right << Printer (value)
   8.311 +		<< std::endl;
   8.312 +    }      
   8.313 +
   8.314 +  NS_TEST_EXPECT_MSG_EQ_TOL (value, expect, int64x64_t (0, tolerance),
   8.315 +			     "Converted string does not match expected string");
   8.316  }
   8.317 +
   8.318  void
   8.319  Int64x64InputOutputTestCase::DoRun (void)
   8.320  {
   8.321    std::cout << std::endl;
   8.322 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.323 +  std::cout << GetParent ()->GetName () << " InputOutput: " << GetName ()
   8.324  	    << std::endl;
   8.325  
   8.326    int64_t tolerance = 0;
   8.327 @@ -222,9 +310,9 @@
   8.328    Int64x64ArithmeticTestCase ();
   8.329    virtual void DoRun (void);
   8.330    void Check (const int        test,
   8.331 -	      const int64x64_t value, const int64x64_t expected);
   8.332 +	      const int64x64_t value, const int64x64_t expect);
   8.333    void Check (const int        test,
   8.334 -	      const int64x64_t value, const int64x64_t expected,
   8.335 +	      const int64x64_t value, const int64x64_t expect,
   8.336  	      const int64x64_t tolerance);
   8.337  };
   8.338  
   8.339 @@ -235,36 +323,40 @@
   8.340  void
   8.341  Int64x64ArithmeticTestCase::Check (const int test,
   8.342  				   const int64x64_t value,
   8.343 -				   const int64x64_t expected)
   8.344 +				   const int64x64_t expect)
   8.345  {
   8.346    int64x64_t zero (0,0);
   8.347 -  Check (test, value, expected, zero);
   8.348 +  Check (test, value, expect, zero);
   8.349  }
   8.350  void
   8.351  Int64x64ArithmeticTestCase::Check (const int test,
   8.352  				   const int64x64_t value,
   8.353 -				   const int64x64_t expected,
   8.354 +				   const int64x64_t expect,
   8.355  				   const int64x64_t tolerance)
   8.356  {
   8.357 +  bool pass = Abs (value - expect) <= tolerance;
   8.358 +  
   8.359    std::cout << GetParent ()->GetName () << " Arithmetic: "
   8.360 -	    << test << ": " << value << " ?= " << expected
   8.361 +	    << (pass ? "pass " : "FAIL ")
   8.362 +	    << test << ": " << value << " == " << expect
   8.363  	    << " (+/- " << tolerance << ")"
   8.364  	    << std::endl;
   8.365    
   8.366 -  NS_TEST_ASSERT_MSG_EQ_TOL ( value, expected, tolerance,
   8.367 +  NS_TEST_ASSERT_MSG_EQ_TOL ( value, expect, tolerance,
   8.368  			      "Arithmetic failure in test case " << test);
   8.369  }
   8.370  
   8.371  void
   8.372  Int64x64ArithmeticTestCase::DoRun (void)
   8.373  {
   8.374 +  const int64x64_t tol1 (0, 1);
   8.375    const int64x64_t zero (0, 0);
   8.376    const int64x64_t one  (1, 0);
   8.377    const int64x64_t two  (2, 0);
   8.378    const int64x64_t thre (3, 0);
   8.379  
   8.380    std::cout << std::endl;
   8.381 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.382 +  std::cout << GetParent ()->GetName () << " Arithmetic: " << GetName ()
   8.383  	    << std::endl;
   8.384    
   8.385    Check ( 0,   zero  -   zero ,   zero  );
   8.386 @@ -290,67 +382,71 @@
   8.387    Check (18,   one   * (-one ),  -one   );
   8.388    Check (19, (-one ) * (-one ),   one   );
   8.389    
   8.390 -  Check (20, (two  * thre ) / thre , two  );
   8.391 +  Check (20,  (two  * thre ) / thre , two  );
   8.392  
   8.393    const int64x64_t frac  = int64x64_t (0, 0xc000000000000000ULL);  // 0.75
   8.394    const int64x64_t fplf2 = frac + frac * frac;  // 1.3125
   8.395 -  NS_TEST_ASSERT_MSG_EQ (frac,  0.75,   "Arithmetic failure fractional part");
   8.396 -  NS_TEST_ASSERT_MSG_EQ (fplf2, 1.3125, "Arithmetic failure fplf2");
   8.397 +  
   8.398 +  Check (21,   frac,              0.75);
   8.399 +  Check (22,   fplf2,             1.3125);
   8.400    
   8.401    const int64x64_t zerof = zero + frac;
   8.402 -  NS_TEST_ASSERT_MSG_EQ (zerof, frac,   "Arithmetic failure adding fractional part");
   8.403    const int64x64_t onef  = one  + frac;
   8.404    const int64x64_t twof  = two  + frac;
   8.405    const int64x64_t thref = thre + frac;
   8.406 +
   8.407 +  Check (23,   zerof,             frac);
   8.408    
   8.409 -  Check (21,   zerof -   zerof,   zero );
   8.410 -  Check (22,   zerof -   onef,   -one  );
   8.411 -  Check (23,   onef  -   onef,    zero );
   8.412 -  Check (24,   onef  -   twof,   -one  );
   8.413 -  Check (25,   onef  - (-onef),   twof  + frac  );
   8.414 -  Check (26, (-onef) - (-twof),   one  );
   8.415 -  Check (27, (-onef) -   twof,   -thref - frac  );
   8.416    
   8.417 -  Check (28,   zerof +   zerof,   zerof + frac  );
   8.418 -  Check (29,   zerof +   onef,    onef  + frac  );
   8.419 -  Check (30,   onef  +   onef,    twof  + frac  );
   8.420 -  Check (31,   onef  +   twof,    thref + frac  );
   8.421 -  Check (32,   onef  + (-onef),   zero  );
   8.422 -  Check (33, (-onef) + (-twof),  -thref - frac  );
   8.423 -  Check (34, (-onef) +   twof,    one   );
   8.424 +  Check (24,   zerof -   zerof,   zero );
   8.425 +  Check (25,   zerof -   onef,   -one  );
   8.426 +  Check (26,   onef  -   onef,    zero );
   8.427 +  Check (27,   onef  -   twof,   -one  );
   8.428 +  Check (28,   onef  - (-onef),   twof  + frac  );
   8.429 +  Check (29 , (-onef) - (-twof),   one  );
   8.430 +  Check (30 , (-onef) -   twof,   -thref - frac  );
   8.431    
   8.432 -  Check (35,   zerof *   zerof,   frac  * frac  );
   8.433 -  Check (36,   zero  *   onef,    zero  );
   8.434 -  Check (37,   zerof *   one,     frac  );
   8.435 +  Check (31,   zerof +   zerof,   zerof + frac  );
   8.436 +  Check (32,   zerof +   onef,    onef  + frac  );
   8.437 +  Check (33,   onef  +   onef,    twof  + frac  );
   8.438 +  Check (34,   onef  +   twof,    thref + frac  );
   8.439 +  Check (35,   onef  + (-onef),   zero  );
   8.440 +  Check (36 , (-onef) + (-twof),  -thref - frac  );
   8.441 +  Check (37, (-onef) +   twof,    one   );
   8.442    
   8.443 -  Check (38,   zerof *   onef,    fplf2 );
   8.444 -  Check (39,   zerof * (-onef),  -fplf2 );
   8.445 -  Check (40,   onef  *   onef,    onef  + fplf2 );
   8.446 -  Check (41,   onef  * (-onef),  -onef  - fplf2 );
   8.447 -  Check (42, (-onef) * (-onef),   onef  + fplf2 );
   8.448 +  Check (38,   zerof *   zerof,   frac  * frac  );
   8.449 +  Check (39 ,   zero  *   onef,    zero  );
   8.450 +  Check (40 ,   zerof *   one,     frac  );
   8.451 +  
   8.452 +  Check (41,   zerof *   onef,    fplf2 );
   8.453 +  Check (42,   zerof * (-onef),  -fplf2 );
   8.454 +  Check (43,   onef  *   onef,    onef  + fplf2 );
   8.455 +  Check (44,   onef  * (-onef),  -onef  - fplf2 );
   8.456 +  Check (45, (-onef) * (-onef),   onef  + fplf2 );
   8.457    
   8.458    
   8.459    // Multiplication followed by division is exact:
   8.460 -  Check (43, (two  * thre ) / thre , two  );
   8.461 -  Check (44, (twof * thref) / thref, twof );
   8.462 +  Check (46, (two  * thre ) / thre , two  );
   8.463 +  Check (47, (twof * thref) / thref, twof );
   8.464  
   8.465    // Division followed by multiplication loses a bit or two:
   8.466 -  int64x64_t tolerance (0, 3);
   8.467 -  Check (45, (two  / thre)  * thre,  two , tolerance );
   8.468 -  Check (46, (twof / thref) * thref, twof, tolerance );
   8.469 +  Check (48, (two  / thre)  * thre,  two , 2 * tol1 );
   8.470 +  Check (49, (twof / thref) * thref, twof, 3 * tol1 );
   8.471  
   8.472    // The example below shows that we really do not lose
   8.473    // much precision internally: it is almost always the
   8.474    // final conversion which loses precision.
   8.475 -  Check (47, (int64x64_t (2000000000) / int64x64_t (3)) * int64x64_t (3),
   8.476 +  Check (50, (int64x64_t (2000000000) / int64x64_t (3)) * int64x64_t (3),
   8.477  	      int64x64_t (1999999999, 0xfffffffffffffffeULL));
   8.478  
   8.479    // Check special values
   8.480 -  Check (48,  int64x64_t (0, 0x159fa87f8aeaad21ULL) * 10,
   8.481 +  Check (51,  int64x64_t (0, 0x159fa87f8aeaad21ULL) * 10,
   8.482  	           int64x64_t (0, 0xd83c94fb6d2ac34aULL));
   8.483    
   8.484  }
   8.485  
   8.486 +
   8.487 +
   8.488  /**
   8.489   * See \bugid{455}
   8.490   */
   8.491 @@ -371,7 +467,10 @@
   8.492  Int64x64Bug455TestCase::Check (const double result, const double expect,
   8.493  			       const std::string & msg)
   8.494  {
   8.495 +  bool pass = result == expect;
   8.496 +  
   8.497    std::cout << GetParent ()->GetName () << " Bug 455: "
   8.498 +	    << (pass ? "pass " : "FAIL ")
   8.499  	    << "res: "  << result
   8.500  	    << " exp: " << expect
   8.501  	    << ": " << msg
   8.502 @@ -384,7 +483,7 @@
   8.503  Int64x64Bug455TestCase::DoRun (void)
   8.504  {
   8.505    std::cout << std::endl;
   8.506 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.507 +  std::cout << GetParent ()->GetName () << " Bug 455: " << GetName ()
   8.508  	    << std::endl;
   8.509    
   8.510    int64x64_t a = int64x64_t (0.1);
   8.511 @@ -408,6 +507,8 @@
   8.512    Check (a.GetDouble (), -2.5, "only second operand negative");
   8.513  }
   8.514  
   8.515 +
   8.516 +
   8.517  /**
   8.518   * See \bugid{863}
   8.519   */
   8.520 @@ -428,7 +529,10 @@
   8.521  Int64x64Bug863TestCase::Check (const double result, const double expect,
   8.522  			       const std::string & msg)
   8.523  {
   8.524 +  bool pass = result == expect;
   8.525 +  
   8.526    std::cout << GetParent ()->GetName () << " Bug 863: "
   8.527 +	    << (pass ? "pass " : "FAIL ")
   8.528  	    << "res: "  << result
   8.529  	    << " exp: " << expect
   8.530  	    << ": " << msg
   8.531 @@ -441,7 +545,7 @@
   8.532  Int64x64Bug863TestCase::DoRun (void)
   8.533  {
   8.534    std::cout << std::endl;
   8.535 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.536 +  std::cout << GetParent ()->GetName () << " Bug 863: " << GetName ()
   8.537  	    << std::endl;
   8.538    
   8.539    int64x64_t a = int64x64_t (0.9);
   8.540 @@ -467,6 +571,7 @@
   8.541    Check (a.GetDouble (), 1.0, "both arguments negative");
   8.542  }
   8.543  
   8.544 +
   8.545  /**
   8.546   * See \bugid{1786}
   8.547   */
   8.548 @@ -490,28 +595,43 @@
   8.549  {
   8.550    int64x64_t value (0, low);
   8.551    std::ostringstream oss;
   8.552 -  oss << std::scientific << std::setprecision (21) << value;
   8.553 -  
   8.554 -  std::cout << GetParent ()->GetName () << " Bug 1786: "
   8.555 -	    << "    0x" << std::hex << std::setw (16) << low << std::dec
   8.556 -	    << " = "    << oss.str ()
   8.557 -	    << std::endl;
   8.558 +  oss << std::scientific << std::setprecision (22) << value;
   8.559  
   8.560    if (tolerance == 0)
   8.561      {
   8.562 +      bool pass = oss.str () == str;
   8.563 +  
   8.564 +      std::cout << GetParent ()->GetName () << " Bug 1786: "
   8.565 +		<< (pass ? "pass " : "FAIL ")
   8.566 +		<< "    0x" << std::hex << std::setw (16) << low << std::dec
   8.567 +		<< " = "    << oss.str ();
   8.568 +      if (!pass)
   8.569 +	{
   8.570 +	  std::cout << ", expected " << str;
   8.571 +	}
   8.572 +      std::cout << std::endl;
   8.573 +
   8.574        NS_TEST_EXPECT_MSG_EQ (oss.str (), str,
   8.575  			     "Fraction string not correct");
   8.576      }
   8.577    else
   8.578      {
   8.579 -      // No obvious way to implement a tolerance
   8.580 +      // No obvious way to implement a tolerance on the strings
   8.581 +      
   8.582 +      std::cout << GetParent ()->GetName () << " Bug 1786: "
   8.583 +		<< "skip "
   8.584 +		<< "    0x" << std::hex << std::setw (16) << low << std::dec
   8.585 +		<< " = "    << oss.str ()
   8.586 +		<< ", expected " << str
   8.587 +		<< std::endl;
   8.588 +
   8.589      }
   8.590  }
   8.591  void
   8.592  Int64x64Bug1786TestCase::DoRun (void)
   8.593  {
   8.594    std::cout << std::endl;
   8.595 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.596 +  std::cout << GetParent ()->GetName () << " But 1786: " << GetName ()
   8.597  	    << std::endl;
   8.598  
   8.599    int64_t tolerance = 0;
   8.600 @@ -520,72 +640,81 @@
   8.601        // Darwin 12.5.0 (Mac 10.8.5) g++ 4.2.1
   8.602        tolerance = 1;
   8.603      }
   8.604 -  
   8.605 -  Check (                 1ULL, "+0.000000000000000000054");
   8.606 -  Check (                 2ULL, "+0.000000000000000000108");
   8.607 -  Check (                 3ULL, "+0.000000000000000000162");
   8.608 -  Check (                 4ULL, "+0.000000000000000000216");
   8.609 -  Check (                 5ULL, "+0.000000000000000000271");
   8.610 -  Check (                 6ULL, "+0.000000000000000000325");
   8.611 -  Check (                 7ULL, "+0.000000000000000000379");
   8.612 -  Check (                 8ULL, "+0.000000000000000000433");
   8.613 -  Check (                 9ULL, "+0.000000000000000000487");
   8.614 -  Check (               0xAULL, "+0.000000000000000000542");
   8.615 -  Check (               0xFULL, "+0.000000000000000000813");
   8.616 -  Check (              0xF0ULL, "+0.000000000000000013010");
   8.617 -  Check (             0xF00ULL, "+0.000000000000000208166");
   8.618 -  Check (            0xF000ULL, "+0.000000000000003330669");
   8.619 -  Check (           0xF0000ULL, "+0.000000000000053290705");
   8.620 -  Check (          0xF00000ULL, "+0.000000000000852651282");
   8.621 -  Check (         0xF000000ULL, "+0.000000000013642420526");
   8.622 -  Check (        0xF0000000ULL, "+0.000000000218278728425");
   8.623 -  Check (       0xF00000000ULL, "+0.000000003492459654808");
   8.624 -  Check (      0xF000000000ULL, "+0.000000055879354476928");
   8.625 -  Check (     0xF0000000000ULL, "+0.000000894069671630859");
   8.626 -  Check (    0xF00000000000ULL, "+0.000014305114746093750");
   8.627 -  Check (   0xF000000000000ULL, "+0.000228881835937500000");
   8.628 -  Check (  0xF0000000000000ULL, "+0.003662109375000000000");
   8.629 +
   8.630 +  // Some of these values differ from the DoubleTestCase
   8.631 +  // by one count in the last place
   8.632 +  // because operator<< truncates the last output digit,
   8.633 +  // instead of rounding.
   8.634 +  Check (                 1ULL, "+0.0000000000000000000542");
   8.635 +  Check (                 2ULL, "+0.0000000000000000001084");
   8.636 +  Check (                 3ULL, "+0.0000000000000000001626");
   8.637 +  Check (                 4ULL, "+0.0000000000000000002168");
   8.638 +  Check (                 5ULL, "+0.0000000000000000002710");
   8.639 +  Check (                 6ULL, "+0.0000000000000000003253");
   8.640 +  Check (                 7ULL, "+0.0000000000000000003795");
   8.641 +  Check (                 8ULL, "+0.0000000000000000004337");
   8.642 +  Check (                 9ULL, "+0.0000000000000000004879");
   8.643 +  Check (               0xAULL, "+0.0000000000000000005421");
   8.644 +  Check (               0xFULL, "+0.0000000000000000008132");
   8.645 +  Check (              0xF0ULL, "+0.0000000000000000130104");
   8.646 +  Check (             0xF00ULL, "+0.0000000000000002081668");
   8.647 +  Check (            0xF000ULL, "+0.0000000000000033306691");
   8.648 +  Check (           0xF0000ULL, "+0.0000000000000532907052");
   8.649 +  Check (          0xF00000ULL, "+0.0000000000008526512829");
   8.650 +  Check (         0xF000000ULL, "+0.0000000000136424205266");
   8.651 +  Check (        0xF0000000ULL, "+0.0000000002182787284255");
   8.652 +  Check (       0xF00000000ULL, "+0.0000000034924596548080");
   8.653 +  Check (      0xF000000000ULL, "+0.0000000558793544769287");
   8.654 +  Check (     0xF0000000000ULL, "+0.0000008940696716308594");
   8.655 +  Check (    0xF00000000000ULL, "+0.0000143051147460937500");
   8.656 +  Check (   0xF000000000000ULL, "+0.0002288818359375000000");
   8.657 +  Check (  0xF0000000000000ULL, "+0.0036621093750000000000");
   8.658 +  Check ( 0xF00000000000000ULL, "+0.0585937500000000000000");
   8.659    std::cout << std::endl;
   8.660 -  Check (0x7FFFFFFFFFFFFFFDULL, "+0.499999999999999999837", tolerance);
   8.661 -  Check (0x7FFFFFFFFFFFFFFEULL, "+0.499999999999999999891", tolerance);
   8.662 -  Check (0x7FFFFFFFFFFFFFFFULL, "+0.499999999999999999945", tolerance);
   8.663 -  Check (0x8000000000000000ULL, "+0.500000000000000000000");
   8.664 -  Check (0x8000000000000001ULL, "+0.500000000000000000054", tolerance);
   8.665 -  Check (0x8000000000000002ULL, "+0.500000000000000000108", tolerance);
   8.666 -  Check (0x8000000000000003ULL, "+0.500000000000000000162", tolerance);
   8.667 +  Check (0x7FFFFFFFFFFFFFFDULL, "+0.4999999999999999998374", tolerance);
   8.668 +  Check (0x7FFFFFFFFFFFFFFEULL, "+0.4999999999999999998916", tolerance);
   8.669 +  Check (0x7FFFFFFFFFFFFFFFULL, "+0.4999999999999999999458", tolerance);
   8.670 +  Check (0x8000000000000000ULL, "+0.5000000000000000000000");
   8.671 +  Check (0x8000000000000001ULL, "+0.5000000000000000000542", tolerance);
   8.672 +  Check (0x8000000000000002ULL, "+0.5000000000000000001084", tolerance);
   8.673 +  Check (0x8000000000000003ULL, "+0.5000000000000000001626", tolerance);
   8.674    std::cout << std::endl;
   8.675 -  Check (0xF000000000000000ULL, "+0.937500000000000000000");
   8.676 -  Check (0xFF00000000000000ULL, "+0.996093750000000000000");
   8.677 -  Check (0xFFF0000000000000ULL, "+0.999755859375000000000");
   8.678 -  Check (0xFFFF000000000000ULL, "+0.999984741210937500000");
   8.679 -  Check (0xFFFFF00000000000ULL, "+0.999999046325683593750");
   8.680 -  Check (0xFFFFFF0000000000ULL, "+0.999999940395355224609");
   8.681 -  Check (0xFFFFFFF000000000ULL, "+0.999999996274709701538");
   8.682 -  Check (0xFFFFFFFF00000000ULL, "+0.999999999767169356346");
   8.683 -  Check (0xFFFFFFFFF0000000ULL, "+0.999999999985448084771");
   8.684 -  Check (0xFFFFFFFFFF000000ULL, "+0.999999999999090505298");
   8.685 -  Check (0xFFFFFFFFFFF00000ULL, "+0.999999999999943156581");
   8.686 -  Check (0xFFFFFFFFFFFF0000ULL, "+0.999999999999996447286");
   8.687 -  Check (0xFFFFFFFFFFFFF000ULL, "+0.999999999999999777955");
   8.688 -  Check (0xFFFFFFFFFFFFFF00ULL, "+0.999999999999999986122");
   8.689 -  Check (0xFFFFFFFFFFFFFFF0ULL, "+0.999999999999999999132");
   8.690 -  Check (0xFFFFFFFFFFFFFFFFULL, "+0.999999999999999999945", tolerance);
   8.691 +  Check (0xF000000000000000ULL, "+0.9375000000000000000000");
   8.692 +  Check (0xFF00000000000000ULL, "+0.9960937500000000000000");
   8.693 +  Check (0xFFF0000000000000ULL, "+0.9997558593750000000000");
   8.694 +  Check (0xFFFF000000000000ULL, "+0.9999847412109375000000");
   8.695 +  Check (0xFFFFF00000000000ULL, "+0.9999990463256835937500");
   8.696 +  Check (0xFFFFFF0000000000ULL, "+0.9999999403953552246094");
   8.697 +  Check (0xFFFFFFF000000000ULL, "+0.9999999962747097015381");
   8.698 +  Check (0xFFFFFFFF00000000ULL, "+0.9999999997671693563461");
   8.699 +  Check (0xFFFFFFFFF0000000ULL, "+0.9999999999854480847716");
   8.700 +  Check (0xFFFFFFFFFF000000ULL, "+0.9999999999990905052982");
   8.701 +  Check (0xFFFFFFFFFFF00000ULL, "+0.9999999999999431565811");
   8.702 +  Check (0xFFFFFFFFFFFF0000ULL, "+0.9999999999999964472863");
   8.703 +  Check (0xFFFFFFFFFFFFF000ULL, "+0.9999999999999997779554");
   8.704 +  Check (0xFFFFFFFFFFFFFF00ULL, "+0.9999999999999999861222");
   8.705 +  Check (0xFFFFFFFFFFFFFFF0ULL, "+0.9999999999999999991326");
   8.706 +  Check (0xFFFFFFFFFFFFFFF5ULL, "+0.9999999999999999994037", tolerance);
   8.707 +  Check (0xFFFFFFFFFFFFFFF6ULL, "+0.9999999999999999994579", tolerance);
   8.708 +  Check (0xFFFFFFFFFFFFFFF7ULL, "+0.9999999999999999995121", tolerance);
   8.709 +  Check (0xFFFFFFFFFFFFFFF8ULL, "+0.9999999999999999995663", tolerance);
   8.710 +  Check (0xFFFFFFFFFFFFFFF9ULL, "+0.9999999999999999996205", tolerance);
   8.711 +  Check (0xFFFFFFFFFFFFFFFAULL, "+0.9999999999999999996747", tolerance);
   8.712 +  Check (0xFFFFFFFFFFFFFFFBULL, "+0.9999999999999999997289", tolerance);
   8.713 +  Check (0xFFFFFFFFFFFFFFFCULL, "+0.9999999999999999997832", tolerance);
   8.714 +  Check (0xFFFFFFFFFFFFFFFDULL, "+0.9999999999999999998374", tolerance);
   8.715 +  Check (0xFFFFFFFFFFFFFFFEULL, "+0.9999999999999999998916", tolerance);
   8.716 +  Check (0xFFFFFFFFFFFFFFFFULL, "+0.9999999999999999999458", tolerance);
   8.717  }
   8.718  
   8.719 +
   8.720  class Int64x64CompareTestCase : public TestCase
   8.721  {
   8.722  public:
   8.723    Int64x64CompareTestCase ();
   8.724    virtual void DoRun (void);
   8.725  
   8.726 -#if defined (__GNUC__)
   8.727 -#if (__GNUC__ == 4 && (4 <= __GNUC_MINOR__ && __GNUC_MINOR__ <= 6))
   8.728 -  // gcc-4.4 is overeager to optimize away signed comparisons
   8.729 -  // which makes it hard to test comparison operators
   8.730 -  __attribute__ ((optimize ("no-strict-overflow")))
   8.731 -#endif
   8.732 -#endif
   8.733 -  void Check (const bool result, const bool expected,
   8.734 +  void Check (const bool result, const bool expect,
   8.735  	      const std::string & msg);
   8.736  };
   8.737  Int64x64CompareTestCase::Int64x64CompareTestCase ()
   8.738 @@ -593,21 +722,24 @@
   8.739  {
   8.740  }
   8.741  void
   8.742 -Int64x64CompareTestCase::Check (const bool result, const bool expected,
   8.743 +Int64x64CompareTestCase::Check (const bool result, const bool expect,
   8.744  				const std::string & msg)
   8.745  {
   8.746 +  bool pass = result == expect;
   8.747 +  
   8.748    std::cout << GetParent ()->GetName () << " Compare: "
   8.749 -	    << (result == expected ? "pass:  " : "FAIL:  ") << msg
   8.750 +	    << (pass ? "pass " : "FAIL ")
   8.751 +	    << msg
   8.752  	    << std::endl;
   8.753    
   8.754 -  NS_TEST_ASSERT_MSG_EQ (result, expected, msg);
   8.755 +  NS_TEST_ASSERT_MSG_EQ (result, expect, msg);
   8.756  }
   8.757  
   8.758  void
   8.759  Int64x64CompareTestCase::DoRun (void)
   8.760  {
   8.761    std::cout << std::endl;
   8.762 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.763 +  std::cout << GetParent ()->GetName () << " Compare: " << GetName ()
   8.764  	    << std::endl;
   8.765  
   8.766    const int64x64_t zero ( 0, 0);
   8.767 @@ -621,63 +753,67 @@
   8.768    const int64x64_t monef = mone - frac;
   8.769    const int64x64_t mtwof = mtwo - frac;
   8.770    
   8.771 -  Check ( zerof == zerof, true,  "equality, zero");
   8.772 -  Check ( onef  == onef,  true,  "equality, positive");
   8.773 -  Check ( mtwof == mtwof, true,  "equality, negative");
   8.774 -  Check ( zero  == one,   false, "equality false, zero");
   8.775 -  Check ( one   == two,   false, "equality false, unsigned");
   8.776 -  Check ( one   == mone,  false, "equality false, signed");
   8.777 -  Check ( onef  == one,   false, "equality false, fraction");
   8.778 +  Check ( zerof    == zerof, true,  "equality, zero");
   8.779 +  Check ( onef     == onef,  true,  "equality, positive");
   8.780 +  Check ( mtwof    == mtwof, true,  "equality, negative");
   8.781 +  Check ( zero     == one,   false, "equality false, zero");
   8.782 +  Check ( one      == two,   false, "equality false, unsigned");
   8.783 +  Check ( one      == mone,  false, "equality false, signed");
   8.784 +  Check ( onef     == one,   false, "equality false, fraction");
   8.785    std::cout << std::endl;
   8.786  
   8.787 -  Check ( zerof != zerof, false, "inequality, zero");
   8.788 -  Check ( onef  != onef,  false, "inequality, positive");
   8.789 -  Check ( mtwof != mtwof, false, "inequality, negative");
   8.790 -  Check ( zero  != one,   true,  "inequality true, zero");
   8.791 -  Check ( one   != two,   true,  "inequality true, unsigned");
   8.792 -  Check ( one   != mone,  true,  "inequality true, signed");
   8.793 -  Check ( onef  != one,   true,  "inequality true, fraction");
   8.794 +  Check ( zerof    != zerof, false, "inequality, zero");
   8.795 +  Check ( onef     != onef,  false, "inequality, positive");
   8.796 +  Check ( mtwof    != mtwof, false, "inequality, negative");
   8.797 +  Check ( zero     != one,   true,  "inequality true, zero");
   8.798 +  Check ( one      != two,   true,  "inequality true, unsigned");
   8.799 +  Check ( one      != mone,  true,  "inequality true, signed");
   8.800 +  Check ( onef     != one,   true,  "inequality true, fraction");
   8.801    std::cout << std::endl;
   8.802  
   8.803 -  Check ( zerof <  onef,  true,  "less, zerof");
   8.804 -  Check ( zero  <  zerof, true,  "less, zero");
   8.805 -  Check ( one   <  onef,  true,  "less, positive");
   8.806 -  Check ( monef <  mone,  true,  "less, negative");
   8.807 -  Check ( onef  <  one,   false, "less, false, positive");
   8.808 -  Check ( mtwo  <  mtwof, false, "less, false, negative");
   8.809 +  Check ( zerof    <  onef,  true,  "less, zerof");
   8.810 +  Check ( zero     <  zerof, true,  "less, zero");
   8.811 +  Check ( one      <  onef,  true,  "less, positive");
   8.812 +  Check ( monef    <  mone,  true,  "less, negative");
   8.813 +  Check ( onef     <  one,   false, "less, false, positive");
   8.814 +  Check ( mtwo     <  mtwof, false, "less, false, negative");
   8.815    std::cout << std::endl;
   8.816  
   8.817 -  Check ( zerof <= zerof, true,  "less equal, equal, zerof");
   8.818 -  Check ( zero  <= zerof, true,  "less equal, less, zero");
   8.819 -  Check ( onef  <= onef,  true,  "less equal, equal, positive");
   8.820 -  Check ( monef <= mone,  true,  "less equal, less, negative");
   8.821 -  Check ( onef  <= one,   false, "less equal, false, positive");
   8.822 -  Check ( mtwo  <= mtwof, false, "less equal, false, negative");
   8.823 +  Check ( zerof    <= zerof, true,  "less equal, equal, zerof");
   8.824 +  Check ( zero     <= zerof, true,  "less equal, less, zero");
   8.825 +  Check ( onef     <= onef,  true,  "less equal, equal, positive");
   8.826 +  Check ( monef    <= mone,  true,  "less equal, less, negative");
   8.827 +  Check ( onef     <= one,   false, "less equal, false, positive");
   8.828 +  Check ( mtwo     <= mtwof, false, "less equal, false, negative");
   8.829    std::cout << std::endl;
   8.830  
   8.831 -  Check ( onef  >  zerof, true,  "greater, zerof");
   8.832 -  Check ( zerof >  zero,  true,  "greater, zero");
   8.833 -  Check ( onef  >  one,   true,  "greater, positive");
   8.834 -  Check ( mone  >  monef, true,  "greater, negative");
   8.835 -  Check ( one   >  onef,  false, "greater, false, positive");
   8.836 -  Check ( mtwof >  mtwo,  false, "greater, false, negative");
   8.837 +  Check ( onef     >  zerof, true,  "greater, zerof");
   8.838 +  Check ( zerof    >  zero,  true,  "greater, zero");
   8.839 +  Check ( onef     >  one,   true,  "greater, positive");
   8.840 +  Check ( mone     >  monef, true,  "greater, negative");
   8.841 +  Check ( one      >  onef,  false, "greater, false, positive");
   8.842 +  Check ( mtwof    >  mtwo,  false, "greater, false, negative");
   8.843    std::cout << std::endl;
   8.844  
   8.845 -  Check ( zerof >= zerof, true,  "greater equal, equal, zerof");
   8.846 -  Check ( zerof >= zero,  true,  "greater equal, greater, zero");
   8.847 -  Check ( onef  >= onef,  true,  "greater equal, equal, positive");
   8.848 -  Check ( mone  >= monef, true,  "greater equal, greater, negative");
   8.849 -  Check ( one   >= onef,  false, "greater equal, false, positive");
   8.850 -  Check ( mtwof >= mtwo,  false, "greater equal, false, negative");
   8.851 +  Check ( zerof    >= zerof, true,  "greater equal, equal, zerof");
   8.852 +  Check ( zerof    >= zero,  true,  "greater equal, greater, zero");
   8.853 +  Check ( onef     >= onef,  true,  "greater equal, equal, positive");
   8.854 +  Check ( mone     >= monef, true,  "greater equal, greater, negative");
   8.855 +  Check ( one      >= onef,  false, "greater equal, false, positive");
   8.856 +  Check ( mtwof    >= mtwo,  false, "greater equal, false, negative");
   8.857    std::cout << std::endl;
   8.858  
   8.859 -  Check ( (!zero)  == one,  true,  "not zero");
   8.860 -  Check ( (!zerof) == zero, true,  "not zerof");
   8.861 -  Check ( (!one)   == zero, true,  "not one");
   8.862 -  Check ( (+onef) == onef, true, "unary positive");
   8.863 -  Check ( (-onef) == monef, true, "unary negative");
   8.864 +  Check ( zero     == false, true,  "zero   == false");
   8.865 +  Check ( one      == true,  true,  "one    == true");
   8.866 +  Check ( zerof    != false, true,  "zerof  != false");
   8.867 +  Check ( (!zero)  == true,  true,  "!zero  == true");
   8.868 +  Check ( (!zerof) == false, true,  "!zerof == false");
   8.869 +  Check ( (!one)   == false, true,  "!one   == false");
   8.870 +  Check ( (+onef)  == onef,  true, "unary positive");
   8.871 +  Check ( (-onef)  == monef, true, "unary negative");
   8.872  }
   8.873  
   8.874 +
   8.875  class Int64x64InvertTestCase : public TestCase
   8.876  {
   8.877  public:
   8.878 @@ -685,7 +821,7 @@
   8.879    virtual void DoRun (void);
   8.880    void Check (const int64_t factor);
   8.881    void CheckCase (const uint64_t factor,
   8.882 -		  const int64x64_t result, const int64x64_t expected,
   8.883 +		  const int64x64_t result, const int64x64_t expect,
   8.884  		  const std::string & msg,
   8.885  		  const double tolerance = 0);
   8.886  };
   8.887 @@ -697,27 +833,30 @@
   8.888  void
   8.889  Int64x64InvertTestCase::CheckCase (const uint64_t factor,
   8.890  				   const int64x64_t result,
   8.891 -				   const int64x64_t expected,
   8.892 +				   const int64x64_t expect,
   8.893  				   const std::string & msg,
   8.894  				   const double tolerance /* = 0 */)
   8.895  {
   8.896 -  std::cout << GetParent ()->GetName () << " Invert: "
   8.897 -	    << factor << ": ";
   8.898 -  if (result == expected)
   8.899 +  bool pass = Abs (result - expect) <= tolerance;
   8.900 +  
   8.901 +  std::cout << GetParent ()->GetName () << " Invert: ";
   8.902 +
   8.903 +  if (pass)
   8.904      {
   8.905 -      std::cout << "pass:  ";
   8.906 +      std::cout << "pass:  " << factor << ": ";
   8.907 +
   8.908      }
   8.909    else
   8.910      {
   8.911 -      std::cout << "FAIL:  "
   8.912 +      std::cout << "FAIL:  " << factor << ": "
   8.913  		<< "(res: " << result
   8.914 -		<< " exp: " << expected
   8.915 +		<< " exp: " << expect
   8.916  		<< " tol: " << tolerance << ")  ";
   8.917      }
   8.918    std::cout << msg 
   8.919  	    << std::endl;
   8.920    
   8.921 -  NS_TEST_ASSERT_MSG_EQ_TOL (result, expected, int64x64_t(tolerance), msg);
   8.922 +  NS_TEST_ASSERT_MSG_EQ_TOL (result, expect, int64x64_t(tolerance), msg);
   8.923  }
   8.924  
   8.925  void
   8.926 @@ -756,7 +895,7 @@
   8.927  Int64x64InvertTestCase::DoRun (void)
   8.928  {
   8.929    std::cout << std::endl;
   8.930 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
   8.931 +  std::cout << GetParent ()->GetName () << " Invert: " << GetName ()
   8.932  	    << std::endl;
   8.933    
   8.934    Check (2);
   8.935 @@ -784,6 +923,216 @@
   8.936  }
   8.937  
   8.938  
   8.939 +class Int64x64DoubleTestCase : public TestCase
   8.940 +{
   8.941 +public:
   8.942 +  Int64x64DoubleTestCase ();
   8.943 +  virtual void DoRun (void);
   8.944 +  void Check (const int64_t intPart);
   8.945 +  void Check (const long double value,
   8.946 +	      const int64_t intPart,
   8.947 +	      const uint64_t lo);
   8.948 +private:
   8.949 +  long double m_last;
   8.950 +  int64x64_t  m_deltaMax;
   8.951 +  int         m_deltaCount;
   8.952 +};
   8.953 +
   8.954 +Int64x64DoubleTestCase::Int64x64DoubleTestCase ()
   8.955 +  : TestCase ("Construct from floating point.")
   8.956 +{
   8.957 +}
   8.958 +
   8.959 +void
   8.960 +Int64x64DoubleTestCase::Check (const long double value,
   8.961 +			       const int64_t intPart,
   8.962 +			       const uint64_t lo)
   8.963 +{
   8.964 +  // Construct the expected value
   8.965 +  int64x64_t expect = int64x64_t (0, lo);
   8.966 +  expect += intPart;
   8.967 +
   8.968 +  // Actual value of conversion from double
   8.969 +  const int64x64_t result = int64x64_t (value);
   8.970 +
   8.971 +  // Make tolerance depend on magnitude of value
   8.972 +  long double margin = 0;
   8.973 +  if (int64x64_t::implementation == int64x64_t::ld_impl)
   8.974 +    {
   8.975 +      // Darwin 12.5.0 (Mac 10.8.5) g++ 4.2.1
   8.976 +      margin = 1.0;
   8.977 +    }
   8.978 +  
   8.979 +  const int64x64_t tolerance = (margin + std::fabs (value))
   8.980 +    * std::numeric_limits<long double>::epsilon ();
   8.981 +  
   8.982 +  const int64x64_t delta = Abs (result - expect);
   8.983 +  const bool skip = value == m_last;
   8.984 +  const bool pass = delta <= tolerance;
   8.985 +  
   8.986 +  // Save stream format flags
   8.987 +  std::ios_base::fmtflags ff = std::cout.flags ();
   8.988 +  std::cout << std::fixed << std::setprecision (22);
   8.989 +  
   8.990 +  std::cout << GetParent ()->GetName () << " Double: "
   8.991 +	    << (skip ? "skip " : (pass ? "pass " : "FAIL "))
   8.992 +	    << std::showpos << value << " == " 
   8.993 +	    << Printer (result)
   8.994 +	    << std::endl;
   8.995 +  
   8.996 +  // Log non-zero delta
   8.997 +  if ( delta > int64x64_t() )
   8.998 +    {
   8.999 +      std::cout << GetParent ()->GetName ()
  8.1000 +		<< std::left  << std::setw (43) << "         expected"
  8.1001 +		<< std::right << Printer (expect)
  8.1002 +		<< std::endl;
  8.1003 +
  8.1004 +      if (delta == tolerance)
  8.1005 +	{
  8.1006 +	  std::cout << GetParent ()->GetName ()
  8.1007 +		    << std::left  << std::setw (43) << "         delta = tolerance"
  8.1008 +		    << std::right << Printer (delta)
  8.1009 +		    << std::endl;
  8.1010 +	}
  8.1011 +      else
  8.1012 +	{
  8.1013 +	  std::cout << GetParent ()->GetName ()
  8.1014 +		    << std::left  << std::setw (43) << "         delta"
  8.1015 +		    << std::right << Printer (delta)
  8.1016 +		    << std::endl;
  8.1017 +	  std::cout << GetParent ()->GetName ()
  8.1018 +		    << std::left  << std::setw (43) << "         +/-"
  8.1019 +		    << std::right << Printer (tolerance)
  8.1020 +		    << std::endl;
  8.1021 +	}
  8.1022 +      
  8.1023 +      ++m_deltaCount;
  8.1024 +      
  8.1025 +      if ( delta > m_deltaMax )
  8.1026 +	{
  8.1027 +	  m_deltaMax = delta;
  8.1028 +	}
  8.1029 +    }
  8.1030 +  
  8.1031 +  NS_TEST_ASSERT_MSG_EQ_TOL (result, expect, tolerance,
  8.1032 +			     "int64x64_t (long double) failed");
  8.1033 +  m_last = value;
  8.1034 +  std::cout.flags (ff);
  8.1035 +
  8.1036 +}
  8.1037 +
  8.1038 +void
  8.1039 +Int64x64DoubleTestCase::Check (const int64_t intPart)
  8.1040 +{
  8.1041 +  std::cout << std::endl;
  8.1042 +  std::cout << GetParent ()->GetName () << " Double: "
  8.1043 +	    << "integer: " << intPart
  8.1044 +	    << std::endl;
  8.1045 +  m_last = intPart;
  8.1046 +  m_deltaCount = 0;
  8.1047 +
  8.1048 +  // Nudging the integer part eliminates deltas around 0
  8.1049 +  long double v = intPart;
  8.1050 +  
  8.1051 +  Check (v +0.0000000000000000000542L, intPart,                0x1ULL);
  8.1052 +  Check (v +0.0000000000000000001084L, intPart,                0x2ULL);
  8.1053 +  Check (v +0.0000000000000000001626L, intPart,                0x3ULL);
  8.1054 +  Check (v +0.0000000000000000002168L, intPart,                0x4ULL);
  8.1055 +  Check (v +0.0000000000000000002710L, intPart,                0x5ULL);
  8.1056 +  Check (v +0.0000000000000000003253L, intPart,                0x6ULL);
  8.1057 +  Check (v +0.0000000000000000003795L, intPart,                0x7ULL);
  8.1058 +  Check (v +0.0000000000000000004337L, intPart,                0x8ULL);
  8.1059 +  Check (v +0.0000000000000000004879L, intPart,                0x9ULL);
  8.1060 +  Check (v +0.0000000000000000005421L, intPart,                0xAULL);
  8.1061 +  Check (v +0.0000000000000000008132L, intPart,                0xFULL);
  8.1062 +  Check (v +0.0000000000000000130104L, intPart,               0xF0ULL);
  8.1063 +  Check (v +0.0000000000000002081668L, intPart,              0xF00ULL);
  8.1064 +  Check (v +0.0000000000000033306691L, intPart,             0xF000ULL);
  8.1065 +  Check (v +0.0000000000000532907052L, intPart,            0xF0000ULL);
  8.1066 +  Check (v +0.0000000000008526512829L, intPart,           0xF00000ULL);
  8.1067 +  Check (v +0.0000000000136424205266L, intPart,          0xF000000ULL);
  8.1068 +  Check (v +0.0000000002182787284255L, intPart,         0xF0000000ULL);
  8.1069 +  Check (v +0.0000000034924596548080L, intPart,        0xF00000000ULL);
  8.1070 +  Check (v +0.0000000558793544769287L, intPart,       0xF000000000ULL);
  8.1071 +  Check (v +0.0000008940696716308594L, intPart,      0xF0000000000ULL);
  8.1072 +  Check (v +0.0000143051147460937500L, intPart,     0xF00000000000ULL);
  8.1073 +  Check (v +0.0002288818359375000000L, intPart,    0xF000000000000ULL);
  8.1074 +  Check (v +0.0036621093750000000000L, intPart,   0xF0000000000000ULL);
  8.1075 +  Check (v +0.0585937500000000000000L, intPart,  0xF00000000000000ULL);
  8.1076 +  std::cout << std::endl;
  8.1077 +  Check (v +0.4999999999999999998374L, intPart, 0x7FFFFFFFFFFFFFFDULL);
  8.1078 +  Check (v +0.4999999999999999998916L, intPart, 0x7FFFFFFFFFFFFFFEULL);
  8.1079 +  Check (v +0.4999999999999999999458L, intPart, 0x7FFFFFFFFFFFFFFFULL);
  8.1080 +  Check (v +0.5000000000000000000000L, intPart, 0x8000000000000000ULL);
  8.1081 +  Check (v +0.5000000000000000000542L, intPart, 0x8000000000000001ULL);
  8.1082 +  Check (v +0.5000000000000000001084L, intPart, 0x8000000000000002ULL);
  8.1083 +  Check (v +0.5000000000000000001626L, intPart, 0x8000000000000003ULL);
  8.1084 +  std::cout << std::endl;
  8.1085 +  Check (v +0.9375000000000000000000L, intPart, 0xF000000000000000ULL);
  8.1086 +  Check (v +0.9960937500000000000000L, intPart, 0xFF00000000000000ULL);
  8.1087 +  Check (v +0.9997558593750000000000L, intPart, 0xFFF0000000000000ULL);
  8.1088 +  Check (v +0.9999847412109375000000L, intPart, 0xFFFF000000000000ULL);
  8.1089 +  Check (v +0.9999990463256835937500L, intPart, 0xFFFFF00000000000ULL);
  8.1090 +  Check (v +0.9999999403953552246094L, intPart, 0xFFFFFF0000000000ULL);
  8.1091 +  Check (v +0.9999999962747097015381L, intPart, 0xFFFFFFF000000000ULL);
  8.1092 +  Check (v +0.9999999997671693563461L, intPart, 0xFFFFFFFF00000000ULL);
  8.1093 +  Check (v +0.9999999999854480847716L, intPart, 0xFFFFFFFFF0000000ULL);
  8.1094 +  Check (v +0.9999999999990905052982L, intPart, 0xFFFFFFFFFF000000ULL);
  8.1095 +  Check (v +0.9999999999999431565811L, intPart, 0xFFFFFFFFFFF00000ULL);
  8.1096 +  Check (v +0.9999999999999964472863L, intPart, 0xFFFFFFFFFFFF0000ULL);
  8.1097 +  Check (v +0.9999999999999997779554L, intPart, 0xFFFFFFFFFFFFF000ULL);
  8.1098 +  Check (v +0.9999999999999999861222L, intPart, 0xFFFFFFFFFFFFFF00ULL);
  8.1099 +  Check (v +0.9999999999999999991326L, intPart, 0xFFFFFFFFFFFFFFF0ULL);
  8.1100 +  Check (v +0.9999999999999999994037L, intPart, 0xFFFFFFFFFFFFFFF5ULL);
  8.1101 +  Check (v +0.9999999999999999994579L, intPart, 0xFFFFFFFFFFFFFFF6ULL);
  8.1102 +  Check (v +0.9999999999999999995121L, intPart, 0xFFFFFFFFFFFFFFF7ULL);
  8.1103 +  Check (v +0.9999999999999999995663L, intPart, 0xFFFFFFFFFFFFFFF8ULL);
  8.1104 +  Check (v +0.9999999999999999996205L, intPart, 0xFFFFFFFFFFFFFFF9ULL);
  8.1105 +  Check (v +0.9999999999999999996747L, intPart, 0xFFFFFFFFFFFFFFFAULL);
  8.1106 +  Check (v +0.9999999999999999997289L, intPart, 0xFFFFFFFFFFFFFFFBULL);
  8.1107 +  Check (v +0.9999999999999999997832L, intPart, 0xFFFFFFFFFFFFFFFCULL);
  8.1108 +  Check (v +0.9999999999999999998374L, intPart, 0xFFFFFFFFFFFFFFFDULL);
  8.1109 +  Check (v +0.9999999999999999998916L, intPart, 0xFFFFFFFFFFFFFFFEULL);
  8.1110 +  Check (v +0.9999999999999999999458L, intPart, 0xFFFFFFFFFFFFFFFFULL);
  8.1111 +
  8.1112 +  std::cout << GetParent ()->GetName () << " Double: "
  8.1113 +	    << "integer: " << intPart
  8.1114 +	    << ": delta count: " << m_deltaCount
  8.1115 +	    << ", max: " << Printer (m_deltaMax)
  8.1116 +	    << std::endl;  
  8.1117 +}
  8.1118 +
  8.1119 +void
  8.1120 +Int64x64DoubleTestCase::DoRun (void)
  8.1121 +{
  8.1122 +  std::cout << std::endl;
  8.1123 +  std::cout << GetParent ()->GetName () << " Double: " << GetName ()
  8.1124 +	    << std::endl;
  8.1125 +
  8.1126 +  // Save stream format flags
  8.1127 +  std::ios_base::fmtflags ff = std::cout.flags ();
  8.1128 +  std::cout << std::scientific << std::setprecision (21);
  8.1129 +
  8.1130 +  m_deltaMax = int64x64_t ();
  8.1131 +
  8.1132 +  std::cout << GetParent ()->GetName () << " Double: "
  8.1133 +	    << std::endl;
  8.1134 +    
  8.1135 +  Check (-2);
  8.1136 +  Check (-1);
  8.1137 +  Check ( 0);
  8.1138 +  Check ( 1);
  8.1139 +  Check ( 2);
  8.1140 +
  8.1141 +  std::cout << GetParent ()->GetName () << " Double: "
  8.1142 +	    << "max delta: " << Printer (m_deltaMax)
  8.1143 +	    << std::endl;
  8.1144 +
  8.1145 +  std::cout.flags (ff);
  8.1146 +}
  8.1147 +
  8.1148 +
  8.1149  class Int64x64ImplTestCase : public TestCase
  8.1150  {
  8.1151  public:
  8.1152 @@ -800,7 +1149,7 @@
  8.1153  Int64x64ImplTestCase::DoRun (void)
  8.1154  {
  8.1155    std::cout << std::endl;
  8.1156 -  std::cout << GetParent ()->GetName () << ": " << GetName () << ":"
  8.1157 +  std::cout << GetParent ()->GetName () << " Impl: " << GetName ()
  8.1158  	    << std::endl;
  8.1159  
  8.1160    
  8.1161 @@ -818,16 +1167,16 @@
  8.1162    std::cout << "cairo_impl64:  " << cairo_impl64 << std::endl;
  8.1163    std::cout << "cairo_impl128: " << cairo_impl128 << std::endl;
  8.1164  #endif
  8.1165 -
  8.1166 -  std::cout << std::endl;
  8.1167  }
  8.1168  
  8.1169 -static class Int64x64128TestSuite : public TestSuite
  8.1170 +
  8.1171 +static class Int64x64TestSuite : public TestSuite
  8.1172  {
  8.1173  public:
  8.1174 -  Int64x64128TestSuite ()
  8.1175 +  Int64x64TestSuite ()
  8.1176      : TestSuite ("int64x64", UNIT)
  8.1177    {
  8.1178 +    AddTestCase (new Int64x64ImplTestCase (), TestCase::QUICK);
  8.1179      AddTestCase (new Int64x64HiLoTestCase (), TestCase::QUICK);
  8.1180      AddTestCase (new Int64x64ArithmeticTestCase (), TestCase::QUICK);
  8.1181      AddTestCase (new Int64x64CompareTestCase (), TestCase::QUICK);
  8.1182 @@ -837,6 +1186,13 @@
  8.1183      AddTestCase (new Int64x64Bug863TestCase (), TestCase::QUICK);
  8.1184      AddTestCase (new Int64x64Bug1786TestCase (), TestCase::QUICK);
  8.1185      AddTestCase (new Int64x64InvertTestCase (), TestCase::QUICK);
  8.1186 -    AddTestCase (new Int64x64ImplTestCase (), TestCase::QUICK);
  8.1187 +    AddTestCase (new Int64x64DoubleTestCase (), TestCase::QUICK);
  8.1188    }
  8.1189 -} g_int64x64TestSuite;
  8.1190 +}  g_int64x64TestSuite;
  8.1191 +
  8.1192 +}  // namespace test
  8.1193 +
  8.1194 +}  // namespace int64x64
  8.1195 +
  8.1196 +}  // namespace ns3
  8.1197 +