src/simulator/high-precision-cairo.h
changeset 6496 ed210e7279a7
parent 6419 c08597bde2a0
child 6500 e5298307fdd7
--- a/src/simulator/high-precision-cairo.h	Wed Jul 07 16:22:09 2010 +0200
+++ b/src/simulator/high-precision-cairo.h	Wed Jul 07 16:56:35 2010 +0200
@@ -37,37 +37,6 @@
  * Division operations (there are really really super costly)
  * and Comparison operations (because there are typically a lot of
  * these in any complex timekeeping code).
- *
- * So, the code tries really hard to perform any of these 128 bit
- * operations by doing all arithmetic on 64 bit integers when possible
- * (i.e., when there is no fractional part. This is a very common case).
- * Hence, the following code has a m_fastValue (64 bits) and a
- * m_slowValue (128 bits). m_fastValue is used by default and the code
- * converts it to a m_slowValue when needed.
- *
- * If you want to monitor the efficiency of this strategy, you can
- * enable the macro HP128INC below and call the HighPrecision::PrintStats
- * method at the end of the simulation.
- *
- *  Explanation of Slow and Fast values:
- *
- * HighPrecision class create a fastValue and a slowValue depending on the
- * input number. If the input is an integer with 0 fractional part, it will
- * use the fastValue which will contain the integer in a 64 bits format. If
- * it has a fractional part, the slowValue will be used. It is represented
- * simply as a high part slowValue.hi which will contain the integer part
- * and the fractional part slowValue.lo which will contain the factional
- * part as an integer (obtained by multiplying the fractional part by 2^64).
- *
- * Explanation of Slow and Fast operations:
- *
- * If both operands are fastValues, we will perform fast operations, i-e
- * simply using integer operations. If we have though one of the value is
- * slowValue we need to convert the fastValue into a slow one. It is simply
- * obtained by putting the slowValue.lo = 0 and slowValue.hi = fastValue.
- * After that we apply the slow operation which will be a 128 bits operation
- * with two 128 bits operands.
- *
  */
 
 namespace ns3 {
@@ -77,7 +46,7 @@
 public:
   inline HighPrecision ();
   inline HighPrecision (int64_t value, bool dummy);
-  inline HighPrecision (double value);
+  explicit inline HighPrecision (double value);
 
   inline int64_t GetInteger (void) const;
   inline double GetDouble (void) const;
@@ -85,12 +54,20 @@
   inline void Sub (HighPrecision const &o);
   void Mul (HighPrecision const &o);
   void Div (HighPrecision const &o);
+  void MulByInvert (const HighPrecision &o);
+  static HighPrecision Invert (uint64_t v);
+  
+  void MulFactor (uint64_t factor);
+
 
   inline int Compare (HighPrecision const &o) const;
   inline static HighPrecision Zero (void);
 private:
-  cairo_uint128_t  Mul128 (cairo_uint128_t, cairo_uint128_t ) const;
-  cairo_int128_t Div128 (cairo_int128_t sa, cairo_int128_t sb) const;
+  static inline cairo_uint128_t  Add (cairo_uint128_t a, cairo_uint128_t b);
+  static inline cairo_uint128_t  Sub (cairo_uint128_t a, cairo_uint128_t b);
+  static cairo_uint128_t  Umul (cairo_uint128_t a, cairo_uint128_t b);
+  static cairo_uint128_t Udiv (cairo_uint128_t a, cairo_uint128_t b);
+  static cairo_uint128_t UmulByInvert (cairo_uint128_t a, cairo_uint128_t b);
   inline bool IsNegative (void) const;
 
   cairo_int128_t m_value;
@@ -124,6 +101,31 @@
 {
   return m_value.hi;
 }
+cairo_uint128_t  
+HighPrecision::Add (cairo_uint128_t a, cairo_uint128_t b)
+{
+  cairo_uint128_t result;
+  result.hi = a.hi + b.hi;
+  result.lo = a.lo + b.lo;
+  if (result.lo < a.lo)
+    {
+      result.hi++;
+    }
+  return result;
+}
+cairo_uint128_t  
+HighPrecision::Sub (cairo_uint128_t a, cairo_uint128_t b)
+{
+  cairo_uint128_t result;
+  result.hi = a.hi - b.hi;
+  result.lo = a.lo - b.lo;
+  if (result.lo > a.lo)
+    {
+      result.hi--;
+    }
+  return result;
+}
+
 void
 HighPrecision::Add (HighPrecision const &o)
 {