split out uint64x64 type, optimize
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Tue, 24 Aug 2010 16:36:41 +0200
changeset 7032 17d4c8f349d6
parent 6594 3ace9d888597
child 7033 7adf8cfb1a20
split out uint64x64 type, optimize
src/simulator/high-precision-128.cc
src/simulator/high-precision-128.h
src/simulator/high-precision-cairo.cc
src/simulator/high-precision-cairo.h
src/simulator/high-precision-double.h
src/simulator/high-precision.cc
src/simulator/high-precision.h
src/simulator/nstime.h
src/simulator/time.cc
src/simulator/uint64x64-128.cc
src/simulator/uint64x64-128.h
src/simulator/uint64x64-cairo.cc
src/simulator/uint64x64-cairo.h
src/simulator/uint64x64-double.h
src/simulator/uint64x64.cc
src/simulator/uint64x64.h
src/simulator/wscript
--- a/src/simulator/high-precision-128.cc	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
-#include "high-precision-128.h"
-#include "ns3/abort.h"
-#include "ns3/assert.h"
-#include <math.h>
-#ifdef COUNT_OPS
-#include <iostream>
-#endif
-
-namespace ns3 {
-
-#ifdef COUNT_OPS
-uint128_t HighPrecision::g_nAdd = 0;
-uint128_t HighPrecision::g_nMuli = 0;
-uint128_t HighPrecision::g_nMul = 0;
-uint128_t HighPrecision::g_nDiv = 0;
-uint128_t HighPrecision::g_nCmp = 0;
-HighPrecision::Printer  HighPrecision::g_printer;
-HighPrecision::Printer::~Printer ()
-{
-  std::cout << "add=" << (double)g_nAdd << " mul=" << (double)g_nMul << " div=" << (double)g_nDiv
-	    << " muli=" << (double)g_nMuli << " cmp=" << (double)g_nCmp;
-}
-#endif
-
-#define OUTPUT_SIGN(sa,sb,ua,ub)					\
-  ({bool negA, negB;							\
-    negA = sa < 0;							\
-    negB = sb < 0;							\
-    ua = negA?-sa:sa;							\
-    ub = negB?-sb:sb;							\
-    (negA && !negB) || (!negA && negB);})
-
-
-#define MASK_LO ((((uint128_t)1)<<64)-1)
-#define MASK_HI (~MASK_LO)
-HighPrecision::HighPrecision (int64_t high, uint64_t low)
-{
-  bool is_negative = high<0;
-  m_value = is_negative?-high:high;
-  m_value <<= 64;
-  m_value += low;
-  m_value = is_negative?-m_value:m_value;
-}
-int64_t
-HighPrecision::GetHigh (void) const
-{
-  return GetInteger ();
-}
-uint64_t 
-HighPrecision::GetLow (void) const
-{
-  bool negative = m_value < 0;
-  int128_t v = negative?-m_value:m_value;
-  int128_t low = v & MASK_LO;
-  uint64_t retval = low;
-  return retval;
-}
-
-void
-HighPrecision::Mul (HighPrecision const &o)
-{
-  bool negResult;
-  uint128_t a, b;
-  negResult = OUTPUT_SIGN (m_value, o.m_value, a, b);
-  int128_t result = Umul (a, b);
-  // add the sign to the result
-  result = negResult ? -result : result;
-  m_value = result;
-}
-
-uint128_t
-HighPrecision::Umul (uint128_t a, uint128_t b)
-{
-  INC_MUL;
-  uint128_t aL = a & MASK_LO;
-  uint128_t bL = b & MASK_LO;
-  uint128_t aH = (a >> 64) & MASK_LO;
-  uint128_t bH = (b >> 64) & MASK_LO;
-
-  uint128_t result;
-  uint128_t hiPart,loPart,midPart;
-
-  // Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
-  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
-  // get the low part a.l b.l
-  // multiply the fractional part
-  loPart = aL * bL;
-  // compute the middle part 2^64*(a.h b.l+b.h a.l)
-  midPart = aL * bH + aH * bL;
-  // truncate the low part
-  result = (loPart >> 64) + (midPart & MASK_LO);
-  // compute the high part 2^128 a.h b.h
-  hiPart = aH * bH;
-  // truncate the high part and only use the low part
-  result |= ((hiPart & MASK_LO) << 64) + (midPart & MASK_HI);
-  // if the high part is not zero, put a warning
-  NS_ABORT_MSG_IF ((hiPart & MASK_HI) != 0,
-		   "High precision 128 bits multiplication error: multiplication overflow.");
-  return result;
-}
-void
-HighPrecision::Div (HighPrecision const &o)
-{
-  bool negResult;
-  uint128_t a, b;
-  negResult = OUTPUT_SIGN (m_value, o.m_value, a, b);  
-  int128_t result = Divu (a, b);
-  result = negResult ? -result:result;
-  m_value = result;
-}
-
-uint128_t
-HighPrecision::Divu (uint128_t a, uint128_t b)
-{
-  INC_DIV;
-  uint128_t quo = a / b;
-  uint128_t rem = (a % b);
-  uint128_t result = quo << 64;
-  // Now, manage the remainder
-  uint128_t tmp = rem >> 64;
-  uint128_t div;
-  if (tmp == 0)
-    {
-      rem = rem << 64;
-      div = b;
-    }
-  else
-    {
-      rem = rem;
-      div = b >> 64;
-    }
-  quo = rem / div;
-  result = result + quo;
-  return result;
-}
-
-void 
-HighPrecision::MulByInvert (const HighPrecision &o)
-{
-  bool negResult = m_value < 0;
-  uint128_t a = negResult?-m_value:m_value;
-  uint128_t result = UmulByInvert (a, o.m_value);
-
-  m_value = negResult?-result:result;
-}
-uint128_t
-HighPrecision::UmulByInvert (uint128_t a, uint128_t b)
-{
-  INC_MULI;
-  uint128_t result, ah, bh, al, bl;
-  uint128_t hi, mid;
-  ah = a >> 64;
-  bh = b >> 64;
-  al = a & MASK_LO;
-  bl = b & MASK_LO;
-  hi = ah * bh;
-  mid = ah * bl + al * bh;
-  mid >>= 64;
-  result = ah * bh + mid;
-  return result;
-}
-HighPrecision 
-HighPrecision::Invert (uint64_t v)
-{
-  NS_ASSERT (v > 1);
-  uint128_t a;
-  a = 1;
-  a <<= 64;
-  HighPrecision result;
-  result.m_value = Divu (a, v);
-  HighPrecision tmp = HighPrecision (v, false);
-  tmp.MulByInvert (result);
-  if (tmp.GetInteger () != 1)
-    {
-      result.m_value += 1;
-    }
-  return result;
-}
-
-static uint8_t MostSignificantDigit (uint64_t value)
-{
-  uint8_t n = 0;
-  do
-    {
-      n++;
-      value /= 10;
-    } while (value != 0);
-  return n;
-}
-
-static uint128_t PowerOfTen (uint8_t n)
-{
-  uint128_t retval = 1;
-  while (n > 0)
-    {
-      retval *= 10;
-      n--;
-    }
-  return retval;
-}
-
-std::ostream &operator << (std::ostream &os, const HighPrecision &hp)
-{
-  int64_t hi = hp.GetHigh ();
-  os << ((hi<0)?"-":"+") << ((hi<0)?-hi:hi) << ".";
-  uint128_t low = hp.GetLow ();
-  uint8_t msd = MostSignificantDigit (~((uint64_t)0));
-  do
-    {
-      msd--;
-      uint128_t pow = PowerOfTen (msd);
-      uint8_t digit = low / pow;
-      NS_ASSERT (digit < 10);
-      os << (uint16_t) digit;
-      low -= digit * pow;
-    } while (msd > 0 && low > 0);
-  return os;
-}
-
-static uint64_t ReadDigits (std::string str)
-{
-  const char *buf = str.c_str ();
-  uint64_t retval = 0;
-  while (*buf != 0)
-    {
-      retval *= 10;
-      retval += *buf - 0x30;
-      buf++;
-    }
-  return retval;
-}
-
-std::istream &operator >> (std::istream &is, HighPrecision &hp)
-{
-  std::string str;
-
-  is >> str;
-  bool negative;
-  // skip heading spaces
-  std::string::size_type cur;
-  cur = str.find_first_not_of (" ");
-  std::string::size_type next;
-  // first, remove the sign.
-  next = str.find ("-", cur);
-  if (next != std::string::npos)
-    {
-      negative = true;
-      next++;
-    }
-  else
-    {
-      next = str.find ("+", cur);
-      if (next != std::string::npos)
-	{
-	  next++;
-	}
-      else
-	{
-	  next = cur;
-	}
-      negative = false;
-    }
-  cur = next;
-  int64_t hi;
-  uint64_t lo;
-  next = str.find(".", cur);
-  if (next != std::string::npos)
-    {
-      hi = ReadDigits (str.substr (cur, next-cur));
-      lo = ReadDigits (str.substr (next+1, str.size()-(next+1)));
-    }
-  else
-    {
-      hi = ReadDigits (str.substr (cur, str.size ()-cur));
-      lo = 0;
-    }
-  hi = negative?-hi:hi;
-  hp = HighPrecision (hi, lo);
-  return is;
-}
-
-} // namespace ns3
-
-#include "ns3/test.h"
-
-namespace ns3
-{
-
-class HpFracTestCase : public TestCase
-{
-public:
-  HpFracTestCase ();
-  virtual bool DoRun (void);
-  void CheckFrac (int64_t hi, uint64_t lo);
-};
-
-void 
-HpFracTestCase::CheckFrac (int64_t hi, uint64_t lo)
-{
-  HighPrecision tmp = HighPrecision (hi,lo);
-  NS_TEST_EXPECT_MSG_EQ (tmp.GetHigh (), hi,
-			 "High part does not match");
-  NS_TEST_EXPECT_MSG_EQ (tmp.GetLow (), lo,
-			 "Low part does not match");
-}
-
-HpFracTestCase::HpFracTestCase ()
-  : TestCase ("Check that we can manipulate the high and low part of every number")
-{
-}
-bool
-HpFracTestCase::DoRun (void)
-{
-  CheckFrac (1, 0);
-  CheckFrac (1, 1);
-  CheckFrac (-1, 0);
-  CheckFrac (-1, 1);
-  return GetErrorStatus ();
-}
-
-
-class HpInputTestCase : public TestCase
-{
-public:
-  HpInputTestCase ();
-  virtual bool DoRun (void);
-  void CheckString (std::string str, int64_t hi, uint64_t lo);
-};
-HpInputTestCase::HpInputTestCase ()
-  : TestCase ("Check that we parse HighPrecision numbers as strings")
-{
-}
-void 
-HpInputTestCase::CheckString (std::string str, int64_t hi, uint64_t lo)
-{
-  std::istringstream iss;
-  iss.str (str);
-  HighPrecision hp;
-  iss >> hp;
-  NS_TEST_EXPECT_MSG_EQ (hp.GetHigh (), hi, "High parts do not match for input string " << str);
-  NS_TEST_EXPECT_MSG_EQ (hp.GetLow (), lo, "Low parts do not match for input string " << str);
-}
-bool
-HpInputTestCase::DoRun (void)
-{
-  CheckString ("1", 1, 0);
-  CheckString ("+1", 1, 0);
-  CheckString ("-1", -1, 0);
-  CheckString ("1.0", 1, 0);
-  CheckString ("+1.0", 1, 0);
-  CheckString ("001.0", 1, 0);
-  CheckString ("+001.0", 1, 0);
-  CheckString ("020.0", 20, 0);
-  CheckString ("+020.0", 20, 0);
-  CheckString ("-1.0", -1, 0);
-  CheckString ("-1.0000", -1, 0);
-  CheckString ("1.0000000", 1, 0);
-  CheckString ("1.08446744073709551615", 1, 8446744073709551615LL);
-  CheckString ("-1.08446744073709551615", -1, 8446744073709551615LL);
-  
-  return GetErrorStatus ();
-}
-
-class HpInputOutputTestCase : public TestCase
-{
-public:
-  HpInputOutputTestCase ();
-  virtual bool DoRun (void);
-  void CheckString (std::string str);
-};
-HpInputOutputTestCase::HpInputOutputTestCase ()
-  : TestCase ("Check that we can roundtrip HighPrecision numbers as strings")
-{
-}
-void 
-HpInputOutputTestCase::CheckString (std::string str)
-{
-  std::istringstream iss;
-  iss.str (str);
-  HighPrecision hp;
-  iss >> hp;
-  std::ostringstream oss;
-  oss << hp;
-  NS_TEST_EXPECT_MSG_EQ (oss.str (), str, "Converted string does not match expected string");
-}
-bool
-HpInputOutputTestCase::DoRun (void)
-{
-  CheckString ("+1.0");
-  CheckString ("-1.0");
-  CheckString ("+20.0");
-  CheckString ("+1.08446744073709551615");
-  CheckString ("-1.08446744073709551615");
-  CheckString ("+1.18446744073709551615");
-  CheckString ("-1.18446744073709551615");
-  
-  return GetErrorStatus ();
-}
-
-
-static class HighPrecision128TestSuite : public TestSuite
-{
-public:
-  HighPrecision128TestSuite ()
-    : TestSuite ("high-precision-128", UNIT)
-  {
-    AddTestCase (new HpFracTestCase ());
-    AddTestCase (new HpInputTestCase ());
-    //AddTestCase (new HpOutputTestCase ());
-    AddTestCase (new HpInputOutputTestCase ());
-  }
-} g_highPrecision128TestSuite;
-
-} // namespace ns3
--- a/src/simulator/high-precision-128.h	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2010 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef HIGH_PRECISION_128_H
-#define HIGH_PRECISION_128_H
-
-#include "ns3/simulator-config.h"
-#include <math.h>
-#include <stdint.h>
-#include <iostream>
-
-#define noCOUNT_OPS 1
-
-#if defined(HAVE___UINT128_T) and !defined(HAVE_UINT128_T)
-typedef __uint128_t uint128_t;
-typedef __int128_t int128_t;
-#endif
-
-#ifdef COUNT_OPS
-#define INC_ADD HighPrecision::g_nAdd++
-#define INC_SUB HighPrecision::g_nAdd++
-#define INC_MUL HighPrecision::g_nMul++
-#define INC_DIV HighPrecision::g_nDiv++
-#define INC_MULI HighPrecision::g_nMuli++
-#define INC_CMP HighPrecision::g_nCmp++
-#else
-#define INC_ADD
-#define INC_SUB
-#define INC_MUL
-#define INC_DIV
-#define INC_MULI
-#define INC_CMP
-#endif
-
-namespace ns3 {
-
-class HighPrecision
-{
-public:
-  inline HighPrecision ();
-  explicit HighPrecision (int64_t high, uint64_t low);
-  explicit inline HighPrecision (int64_t value, bool dummy);
-  explicit inline HighPrecision (double value);
-
-  inline int64_t GetInteger (void) const;
-  inline double GetDouble (void) const;
-  inline void Add (HighPrecision const &o);
-  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);
-
-  inline int Compare (HighPrecision const &o) const;
-  inline static HighPrecision Zero (void);
-
-  int64_t GetHigh (void) const;
-  uint64_t GetLow (void) const;
-private:
-  static uint128_t UmulByInvert (uint128_t a, uint128_t b);
-  static uint128_t Umul (uint128_t a, uint128_t b);
-  static uint128_t Divu (uint128_t a, uint128_t b);
-
-  int128_t m_value;
-
-#ifdef COUNT_OPS
-  static uint128_t g_nAdd;
-  static uint128_t g_nMuli;
-  static uint128_t g_nMul;
-  static uint128_t g_nDiv;
-  static uint128_t g_nCmp;
-  static struct Printer {
-    ~Printer ();
-  } g_printer;
-#endif
-};
-
-std::ostream &operator << (std::ostream &os, const HighPrecision &hp);
-std::istream &operator >> (std::istream &is, HighPrecision &hp);
-
-} // namespace ns3
-
-namespace ns3 {
-
-HighPrecision::HighPrecision ()
-  : m_value (0)
-{}
-HighPrecision::HighPrecision (int64_t value, bool dummy)
-  : m_value (value)
-{
-  m_value <<= 64;
-}
-
-
-
-int64_t HighPrecision::GetInteger (void) const
-{
-  bool negative = m_value < 0;
-  int128_t v = negative?-m_value:m_value;
-  v >>= 64;
-  int64_t retval = v;
-  return negative?-retval:retval;
-}
-
-void
-HighPrecision::Add (HighPrecision const &o)
-{
-  INC_ADD;
-  m_value += o.m_value;
-}
-void
-HighPrecision::Sub (HighPrecision const &o)
-{
-  INC_SUB;
-  m_value -= o.m_value;
-}
-
-int 
-HighPrecision::Compare (HighPrecision const &o) const
-{
-  INC_CMP;
-  return (m_value < o.m_value)?-1:(m_value == o.m_value)?0:1;
-}
-
-HighPrecision
-HighPrecision::Zero (void)
-{
-  return HighPrecision ();
-}
-
-#define HP128_MAX_64 18446744073709551615.0
-double 
-HighPrecision::GetDouble (void) const
-{
-  bool is_negative = m_value < 0;
-  uint128_t value = is_negative ? -m_value:m_value;
-  uint64_t hi = value >> 64;
-  uint64_t lo = value;
-  double flo = lo;
-  flo /= HP128_MAX_64;
-  double retval = hi;
-  retval += flo;
-  retval = is_negative ? -retval : retval;
-  return retval;
-}
-HighPrecision::HighPrecision (double value)
-{
-  bool is_negative = value < 0;
-  value = is_negative?-value:value;
-  double hi = floor (value);
-  double lo = (value - hi) * HP128_MAX_64;
-  m_value = (int128_t)hi;
-  m_value <<= 64;
-  m_value += (int128_t)lo;
-  m_value = is_negative?-m_value:m_value;
-}
-#undef HP128_MAX_64
-
-} // namespace ns3
-
-#endif /* HIGH_PRECISION_128_H */
--- a/src/simulator/high-precision-cairo.cc	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "high-precision-cairo.h"
-#include "ns3/test.h"
-#include "ns3/abort.h"
-#include "ns3/assert.h"
-#include <math.h>
-#include <iostream>
-
-namespace ns3 {
-
-
-#define OUTPUT_SIGN(sa,sb,ua,ub)                                        \
-  ({bool negA, negB;                                                    \
-  negA = _cairo_int128_negative (sa);                                   \
-  negB = _cairo_int128_negative (sb);                                   \
-  ua = _cairo_int128_to_uint128 (sa);                                   \
-  ub = _cairo_int128_to_uint128 (sb);                                   \
-  ua = negA ? _cairo_uint128_negate (ua) : ua;                          \
-  ub = negB ? _cairo_uint128_negate (ub) : ub;                          \
-  (negA && !negB) || (!negA && negB);})
-
-void
-HighPrecision::Mul (HighPrecision const &o)
-{
-  cairo_uint128_t a, b, result;
-  bool sign = OUTPUT_SIGN (m_value, o.m_value, a, b);
-  result = Umul (a, b);
-  m_value = sign ? _cairo_uint128_negate (result) : result;
-}
-
-
-/**
- * this function multiplies two 128 bits fractions considering
- * the high 64 bits as the integer part and the low 64 bits
- * as the fractional part. It takes into account the sign
- * of the operands to produce a signed 128 bits result.
- */
-cairo_uint128_t
-HighPrecision::Umul (cairo_uint128_t a, cairo_uint128_t b)
-{
-  cairo_uint128_t result;
-  cairo_uint128_t hiPart,loPart,midPart;
-
-  // Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
-  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
-  // get the low part a.l b.l
-  // multiply the fractional part
-  loPart = _cairo_uint64x64_128_mul (a.lo, b.lo);
-  // compute the middle part 2^64*(a.h b.l+b.h a.l)
-  midPart = _cairo_uint128_add (_cairo_uint64x64_128_mul (a.lo, b.hi),
-                                _cairo_uint64x64_128_mul (a.hi, b.lo));
-  // truncate the low part
-  result.lo = _cairo_uint64_add (loPart.hi,midPart.lo);
-  // compute the high part 2^128 a.h b.h
-  hiPart = _cairo_uint64x64_128_mul (a.hi, b.hi);
-  // truncate the high part and only use the low part
-  result.hi = _cairo_uint64_add (hiPart.lo,midPart.hi);
-  // if the high part is not zero, put a warning
-  NS_ABORT_MSG_IF (hiPart.hi != 0,
-                   "High precision 128 bits multiplication error: multiplication overflow.");
-  return result;
-}
-
-void
-HighPrecision::Div (HighPrecision const &o)
-{
-  cairo_uint128_t a, b, result;
-  bool sign = OUTPUT_SIGN (m_value, o.m_value, a, b);
-  result = Udiv (a, b);
-  m_value = sign ? _cairo_uint128_negate (result) : result;
-}
-
-cairo_uint128_t
-HighPrecision::Udiv (cairo_uint128_t a, cairo_uint128_t b)
-{
-  cairo_uquorem128_t qr = _cairo_uint128_divrem (a, b);
-  cairo_uint128_t result = _cairo_uint128_lsl (qr.quo, 64);
-  // Now, manage the remainder
-  cairo_uint128_t tmp = _cairo_uint128_rsl (qr.rem, 64);
-  cairo_uint128_t zero = _cairo_uint64_to_uint128 (0);
-  cairo_uint128_t rem, div;
-  if (_cairo_uint128_eq (tmp, zero))
-    {
-      rem = _cairo_uint128_lsl (qr.rem, 64);
-      div = b;
-    }
-  else
-    {
-      rem = qr.rem;
-      div = _cairo_uint128_rsl (b, 64);
-    }
-  qr = _cairo_uint128_divrem (rem, div);
-  result = _cairo_uint128_add (result, qr.quo);
-  return result;
-}
-
-void 
-HighPrecision::MulByInvert (const HighPrecision &o)
-{
-  bool negResult = _cairo_int128_negative (m_value);
-  cairo_uint128_t a = negResult?_cairo_int128_negate(m_value):m_value;
-  cairo_uint128_t result = UmulByInvert (a, o.m_value);
-
-  m_value = negResult?_cairo_int128_negate(result):result;
-}
-cairo_uint128_t
-HighPrecision::UmulByInvert (cairo_uint128_t a, cairo_uint128_t b)
-{
-  cairo_uint128_t result;
-  cairo_uint128_t hi, mid;
-  hi = _cairo_uint64x64_128_mul (a.hi, b.hi);
-  mid = _cairo_uint128_add (_cairo_uint64x64_128_mul (a.hi, b.lo),
-                           _cairo_uint64x64_128_mul (a.lo, b.hi));
-  mid.lo = mid.hi;
-  mid.hi = 0;
-  result = _cairo_uint128_add (hi,mid);
-  return result;
-}
-HighPrecision 
-HighPrecision::Invert (uint64_t v)
-{
-  NS_ASSERT (v > 1);
-  cairo_uint128_t a, factor;
-  a.hi = 1;
-  a.lo = 0;
-  factor.hi = 0;
-  factor.lo = v;
-  HighPrecision result;
-  result.m_value = Udiv (a, factor);
-  HighPrecision tmp = HighPrecision (v, false);
-  tmp.MulByInvert (result);
-  if (tmp.GetInteger () != 1)
-    {
-      cairo_uint128_t one = {1, 0};
-      result.m_value = _cairo_uint128_add (result.m_value, one);
-    }
-  return result;
-}
-
-int64_t
-HighPrecision::GetHigh (void) const
-{
-  NS_FATAL_ERROR ("XXX this function unavailable for high-precision-as-cairo; patch requested");
-  return 0;
-}
-
-uint64_t
-HighPrecision::GetLow (void) const
-{
-  NS_FATAL_ERROR ("XXX this function unavailable for high-precision-as-cairo; patch requested");
-  return 0;
-}
-
-std::ostream &operator << (std::ostream &os, const HighPrecision &hp)
-{
-  return os;
-}
-std::istream &operator >> (std::istream &is, HighPrecision &hp)
-{
-  return is;
-}
-
-
-} // namespace ns3
-
-// include directly to allow optimizations within the compilation unit.
-extern "C" {
-#include "cairo-wideint.c"
-}
--- a/src/simulator/high-precision-cairo.h	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef HIGH_PRECISION_CAIRO_H
-#define HIGH_PRECISION_CAIRO_H
-
-#include <stdint.h>
-#include <math.h>
-#include <iostream>
-#include "cairo-wideint-private.h"
-
-/**
- * This file contains an implementation of the HighPrecision class.
- * Each instance of the Time class also contains an instance of this
- * class which is used to perform all the arithmetic operations of
- * the Time class.
- *
- * This code is a bit ugly with a lot of inline methods for speed:
- * profiling this code on anything but the simplest scenarios shows
- * that it is a big bottleneck if great care in its implementation
- * is not performed. My observations are that what dominates are
- * Division operations (there are really really super costly)
- * and Comparison operations (because there are typically a lot of
- * these in any complex timekeeping code).
- */
-
-namespace ns3 {
-
-class HighPrecision
-{
-public:
-  inline HighPrecision ();
-  explicit inline HighPrecision (int64_t value, bool dummy);
-  explicit inline HighPrecision (double value);
-
-  inline int64_t GetInteger (void) const;
-  inline double GetDouble (void) const;
-  inline void Add (HighPrecision const &o);
-  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);
-
-  inline int Compare (HighPrecision const &o) const;
-  inline static HighPrecision Zero (void);
-  int64_t GetHigh (void) const;
-  uint64_t GetLow (void) const;
-private:
-  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;
-};
-
-std::ostream &operator << (std::ostream &os, const HighPrecision &hp);
-std::istream &operator >> (std::istream &is, HighPrecision &hp);
-
-
-} // namespace ns3
-
-namespace ns3 {
-
-HighPrecision::HighPrecision ()
-{
-  m_value.hi = 0;
-  m_value.lo = 0;
-}
-
-HighPrecision::HighPrecision (int64_t value, bool dummy)
-{
-  m_value.hi = value;
-  m_value.lo = 0;
-}
-
-bool 
-HighPrecision::IsNegative (void) const
-{
-  int64_t hi = m_value.hi;
-  return hi < 0;
-}
-
-int64_t
-HighPrecision::GetInteger (void) const
-{
-  return m_value.hi;
-}
-void
-HighPrecision::Add (HighPrecision const &o)
-{
-  m_value.hi += o.m_value.hi;
-  m_value.lo += o.m_value.lo;
-  if (m_value.lo < o.m_value.lo)
-    {
-      m_value.hi++;
-    }
-}
-void
-HighPrecision::Sub (HighPrecision const &o)
-{
-  m_value.hi -= o.m_value.hi;
-  m_value.lo -= o.m_value.lo;
-  if (m_value.lo > o.m_value.lo)
-    {
-      m_value.hi--;
-    }
-}
-int
-HighPrecision::Compare (HighPrecision const &o) const
-{
-  HighPrecision tmp = *this;
-  tmp.Sub (o);
-  return tmp.IsNegative ()?-1:(tmp.m_value.hi == 0 && tmp.m_value.lo == 0)?0:1;
-}
-HighPrecision
-HighPrecision::Zero (void)
-{
-  return HighPrecision ();
-}
-
-
-#define HPCAIRO_MAX_64 18446744073709551615.0
-double HighPrecision::GetDouble (void) const
-{
-  bool is_negative = IsNegative ();
-  cairo_int128_t value = is_negative ? _cairo_int128_negate (m_value) : m_value;
-  double flo = value.lo;
-  flo /= HPCAIRO_MAX_64;
-  double retval = value.hi;
-  retval += flo;
-  retval = is_negative ? -retval: retval;
-  return retval;
-}
-#undef HPCAIRO_MAX_64
-
-#define HPCAIRO_MAX_64 18446744073709551615.0
-HighPrecision::HighPrecision (double value)
-{
-  double fhi = floor (value);
-  int64_t hi = static_cast<int64_t> (fhi);
-  uint64_t lo = (uint64_t) ((value - fhi) * HPCAIRO_MAX_64);
-  m_value.hi = hi;
-  m_value.lo = lo;
-}
-#undef HPCAIRO_MAX_64
-
-} // namespace ns3
-
-#endif /* HIGH_PRECISION_CAIRO_H */
--- a/src/simulator/high-precision-double.h	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef HIGH_PRECISION_DOUBLE_H
-#define HIGH_PRECISION_DOUBLE_H
-
-#include <math.h>
-#include "ns3/fatal-error.h"
-
-namespace ns3 {
-
-/**
- * Obviously, this implementation of the HighPrecision class does
- * not provide the 128 bits accuracy since it uses a an IEEE754 double
- * to store the value. It also does not report overflows.
- * So, it is a nice shortcut but in no way a complete solution.
- */
-
-class HighPrecision
-{
-public:
-  inline HighPrecision ();
-  explicit inline HighPrecision (int64_t value, bool dummy);
-  explicit inline HighPrecision (double value);
-
-  inline int64_t GetInteger (void) const;
-  inline double GetDouble (void) const;
-  inline void Add (HighPrecision const &o);
-  inline void Sub (HighPrecision const &o);
-  inline void Mul (HighPrecision const &o);
-  inline void Div (HighPrecision const &o);
-  inline void MulByInvert (const HighPrecision &o);
-  inline static HighPrecision Invert (uint64_t v);
-
-  inline int Compare (HighPrecision const &o) const;
-  inline static HighPrecision Zero (void);
-  inline int64_t GetHigh (void) const;
-  inline uint64_t GetLow (void) const;
-
-private:
-  double m_value;
-};
-
-inline std::ostream &operator << (std::ostream &os, const HighPrecision &hp);
-inline std::istream &operator >> (std::istream &is, HighPrecision &hp);
-
-} // namespace ns3
-
-namespace ns3 {
-
-HighPrecision::HighPrecision ()
-  : m_value (0.0)
-{
-}
-
-HighPrecision::HighPrecision (int64_t value, bool dummy)
-  : m_value ((double)value)
-{
-}
-
-HighPrecision::HighPrecision (double value)
-  : m_value (value)
-{
-}
-
-int64_t
-HighPrecision::GetInteger (void) const
-{
-  return (int64_t)floor (m_value);
-}
-
-double
-HighPrecision::GetDouble (void) const
-{
-  return m_value;
-}
-void
-HighPrecision::Add (HighPrecision const &o)
-{
-  m_value += o.m_value;
-}
-void
-HighPrecision::Sub (HighPrecision const &o)
-{
-  m_value -= o.m_value;
-}
-void
-HighPrecision::Mul (HighPrecision const &o)
-{
-  m_value *= o.m_value;
-}
-void
-HighPrecision::Div (HighPrecision const &o)
-{
-  m_value /= o.m_value;
-}
-void 
-HighPrecision::MulByInvert (const HighPrecision &o)
-{
-  m_value *= o.m_value;
-}
-HighPrecision 
-HighPrecision::Invert (uint64_t v)
-{
-  return HighPrecision (1.0 / v);
-}
-
-int
-HighPrecision::Compare (HighPrecision const &o) const
-{
-  return (m_value < o.m_value)?-1:(m_value == o.m_value)?0:1;
-}
-HighPrecision
-HighPrecision::Zero (void)
-{
-  return HighPrecision (0,0);
-}
-
-int64_t 
-HighPrecision::GetHigh (void) const
-{
-  return GetInteger ();
-}
-
-uint64_t 
-HighPrecision::GetLow (void) const
-{
-  NS_FATAL_ERROR ("XXX this function unavailable for high-precision-as-double; patch requested");
-  return 0;
-}
-
-std::ostream &operator << (std::ostream &os, const HighPrecision &hp)
-{
-  // XXX stubbed out
-  return os;
-}
-
-std::istream &operator >> (std::istream &is, HighPrecision &hp)
-{
-  // XXX stubbed out
-  return is;
-}
-
-
-} // namespace ns3
-
-#endif /* HIGH_PRECISION_DOUBLE_H  */
--- a/src/simulator/high-precision.cc	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,363 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "high-precision.h"
-
-#include <cmath>
-#include "ns3/assert.h"
-
-
-namespace ns3 {
-
-HighPrecision Abs (HighPrecision const &value)
-{
-  if (value.Compare (HighPrecision::Zero ()) <= 0)
-    {
-      HighPrecision v = HighPrecision::Zero ();
-      v.Sub (value);
-      return v;
-    }
-  else
-    {
-      return value;
-    }
-}
-
-} /* namespace ns3 */
-
-#include "ns3/test.h"
-
-#define CHECK_EXPECTED(a,b) \
-  NS_TEST_ASSERT_MSG_EQ (a.GetInteger (),b,"Arithmetic failure: " << (a.GetInteger ()) << "!=" << (b))
-
-#define V(v) \
-  HighPrecision (v, false)
-
-namespace ns3 {
-
-class HpArithmeticTestCase : public TestCase
-{
-public:
-  HpArithmeticTestCase ();
-  virtual bool DoRun (void);
-};
-
-HpArithmeticTestCase::HpArithmeticTestCase ()
-  : TestCase ("Check basic arithmetic operations")
-{
-}
-bool
-HpArithmeticTestCase::DoRun (void)
-{
-  HighPrecision a, b;
-  a = HighPrecision (1, false);
-  b = HighPrecision (1, false);
-
-  a.Sub (b);
-  CHECK_EXPECTED (a, 0);
-
-  a = V (1);
-  a.Sub (V (2));
-  CHECK_EXPECTED (a, -1);
-
-  a = V (1);
-  a.Sub (V (3));
-  CHECK_EXPECTED (a, -2);
-
-  a = V (1);
-  a.Sub (V (-1));
-  CHECK_EXPECTED (a, 2);
-
-  a = V (1);
-  a.Sub (V (-2));
-  CHECK_EXPECTED (a, 3);
-
-  a = V (-3);
-  a.Sub (V (-4));
-  CHECK_EXPECTED (a, 1);
-
-  a = V (-2);
-  a.Sub (V (3));
-  CHECK_EXPECTED (a, -5);
-
-  a = V (1);
-  a.Add (V (2));
-  CHECK_EXPECTED (a, 3);
-
-  a = V (1);
-  a.Add (V (-3));
-  CHECK_EXPECTED (a, -2);
-
-  a = V (0);
-  a.Add (V (0));
-  CHECK_EXPECTED (a, 0);
-
-  a = V (0);
-  a.Mul (V (0));
-  CHECK_EXPECTED (a, 0);
-  a = V (0);
-  a.Mul (V (1));
-  CHECK_EXPECTED (a, 0);
-  a = V (0);
-  a.Mul (V (-1));
-  CHECK_EXPECTED (a, 0);
-  a = V (1);
-  a.Mul (V (0));
-  CHECK_EXPECTED (a, 0);
-  a = V (1);
-  a.Mul (V (1));
-  CHECK_EXPECTED (a, 1);
-  a = V (1);
-  a.Mul (V (-1));
-  CHECK_EXPECTED (a, -1);
-  a = V (-1);
-  a.Mul (V (-1));
-  CHECK_EXPECTED (a, 1);
-
-  a = V (0);
-  a.Mul (V (1));
-  CHECK_EXPECTED (a, 0);
-  a = V (0);
-  a.Mul (V (-1));
-  CHECK_EXPECTED (a, 0);
-  a = V (1);
-  a.Mul (V (1));
-  CHECK_EXPECTED (a, 1);
-  a = V (1);
-  a.Mul (V (-1));
-  CHECK_EXPECTED (a, -1);
-  a = V (-1);
-  a.Mul (V (1));
-  CHECK_EXPECTED (a, -1);
-  a = V (-1);
-  a.Mul (V (-1));
-  CHECK_EXPECTED (a, 1);
-
-
-
-  a = V (2);
-  a.Mul (V (3));
-  a.Div (V (3));
-  CHECK_EXPECTED (a, 2);
-
-  // Below, the division loses precision because 2/3 is not
-  // representable exactly in 64.64 integers. So, we got
-  // something super close but the final rounding kills us.
-  a = V (2);
-  a.Div (V (3));
-  a.Mul (V (3));
-  CHECK_EXPECTED (a, 1);
-
-  // The example below shows that we really do not lose
-  // much precision internally: it is almost always the
-  // final conversion which loses precision.
-  a = V (2000000000);
-  a.Div (V (3));
-  a.Mul (V (3));
-  CHECK_EXPECTED (a, 1999999999);
-
-  return GetErrorStatus ();
-}
-
-class HpBug455TestCase : public TestCase
-{
-public:
-  HpBug455TestCase ();
-  virtual bool DoRun (void);
-};
-
-HpBug455TestCase::HpBug455TestCase ()
-  : TestCase ("Test case for bug 455")
-{
-}
-bool
-HpBug455TestCase::DoRun (void)
-{
-  HighPrecision a = HighPrecision (0.1);
-  a.Div (HighPrecision (1.25));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 0.08, "The original testcase");
-  a = HighPrecision (0.5);
-  a.Mul (HighPrecision (5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 2.5, "Simple test for multiplication");
-  a = HighPrecision (-0.5);
-  a.Mul (HighPrecision (5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -2.5, "Test sign, first operation negative");
-  a = HighPrecision (-0.5);
-  a.Mul (HighPrecision (-5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 2.5, "both operands negative");
-  a = HighPrecision (0.5);
-  a.Mul (HighPrecision (-5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -2.5, "only second operand negative");
-
-  return GetErrorStatus ();
-}
-
-
-class HpBug863TestCase : public TestCase
-{
-public:
-  HpBug863TestCase ();
-  virtual bool DoRun (void);
-};
-
-HpBug863TestCase::HpBug863TestCase ()
-  : TestCase ("Test case for bug 863")
-{
-}
-bool
-HpBug863TestCase::DoRun (void)
-{
-  HighPrecision a = HighPrecision (0.9);
-  a.Div (HighPrecision (1));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 0.9, "The original testcase");
-  a = HighPrecision (0.5);
-  a.Div (HighPrecision (0.5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 1.0, "Simple test for division");
-  a = HighPrecision (-0.5);
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -0.5, "Check that we actually convert doubles correctly");
-  a.Div (HighPrecision (0.5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -1.0, "first argument negative");
-  a = HighPrecision (0.5);
-  a.Div (HighPrecision (-0.5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -1.0, "second argument negative");
-  a = HighPrecision (-0.5);
-  a.Div (HighPrecision (-0.5));
-  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 1.0, "both arguments negative");
-
-  return GetErrorStatus ();
-}
-
-class HpCompareTestCase : public TestCase
-{
-public:
-  HpCompareTestCase ();
-  virtual bool DoRun (void);
-};
-
-HpCompareTestCase::HpCompareTestCase ()
-  : TestCase ("Check basic compare operations")
-{
-}
-bool
-HpCompareTestCase::DoRun (void)
-{
-  HighPrecision a, b;
-
-  a = V (-1);
-  b = V (1);
-  NS_TEST_ASSERT_MSG_EQ (a.Compare (b), -1, "a is smaller than b");
-  a = V (-1);
-  b = V (-2);
-  NS_TEST_ASSERT_MSG_EQ (a.Compare (b), 1, "a is bigger than b");
-  a = V (-1);
-  b = V (-1);
-  NS_TEST_ASSERT_MSG_EQ (a.Compare (b), 0, "a is equal to b");
-
-  a = V (1);
-  b = V (-1);
-  NS_TEST_ASSERT_MSG_EQ (a.Compare (b), 1, "a is bigger than b");
-  a = V (1);
-  b = V (2);
-  NS_TEST_ASSERT_MSG_EQ (a.Compare (b), -1, "a is smaller than b");
-  a = V (1);
-  b = V (1);
-  NS_TEST_ASSERT_MSG_EQ (a.Compare (b), 0, "a is equal to b");
-
-  return GetErrorStatus ();
-}
-
-class HpInvertTestCase : public TestCase
-{
-public:
-  HpInvertTestCase ();
-  virtual bool DoRun (void);
-};
-
-HpInvertTestCase::HpInvertTestCase ()
-  : TestCase ("Test case for invertion")
-{
-}
-
-bool
-HpInvertTestCase::DoRun (void)
-{
-#define TEST(factor)                                                    \
-  do {                                                                  \
-    HighPrecision a;                                                    \
-    a = HighPrecision::Invert (factor);                                 \
-    HighPrecision b = V (factor);                                       \
-    b.MulByInvert (a);                                                  \
-    NS_TEST_ASSERT_MSG_EQ (b.GetInteger (), 1,                          \
-                           "x * 1/x should be 1 for x=" << factor);     \
-    HighPrecision c = V (1);                                            \
-    c.MulByInvert (a);                                                  \
-    NS_TEST_ASSERT_MSG_EQ (c.GetInteger (), 0,                          \
-                           "1 * 1/x should be 0 for x=" << factor);     \
-    HighPrecision d = V (1);                                            \
-    d.Div (V(factor));                                                  \
-    NS_TEST_ASSERT_MSG_EQ (d.GetDouble (), c.GetDouble (),              \
-                           "1 * 1/x should be equal to 1/x for x=" << factor); \
-    HighPrecision e = V (-factor);                                      \
-    e.MulByInvert (a);                                                  \
-    NS_TEST_ASSERT_MSG_EQ (e.GetInteger (), -1,                         \
-                           "-x * 1/x should be -1 for x=" << factor);   \
-  } while(false)
-
-  TEST(2);
-  TEST(3);
-  TEST(4);
-  TEST(5);
-  TEST(6);
-  TEST(10);
-  TEST(99);
-  TEST(100);
-  TEST(1000);
-  TEST(10000);
-  TEST(100000);
-  TEST(100000);
-  TEST(1000000);
-  TEST(10000000);
-  TEST(100000000);
-  TEST(1000000000);
-  TEST(10000000000LL);
-  TEST(100000000000LL);
-  TEST(1000000000000LL);
-  TEST(10000000000000LL);
-  TEST(100000000000000LL);
-  TEST(1000000000000000LL);
-#undef TEST
-  return GetErrorStatus ();
-}
-
-
-static class HighPrecisionTestSuite : public TestSuite
-{
-public:
-  HighPrecisionTestSuite ()
-    : TestSuite ("high-precision", UNIT)
-  {
-    AddTestCase (new HpArithmeticTestCase ());
-    AddTestCase (new HpBug455TestCase ());
-    AddTestCase (new HpBug863TestCase ());
-    AddTestCase (new HpCompareTestCase ());
-    AddTestCase (new HpInvertTestCase ());
-  }
-} g_highPrecisionTestSuite;
-
-} // namespace ns3
--- a/src/simulator/high-precision.h	Mon Aug 23 19:01:11 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef HIGH_PRECISION_H
-#define HIGH_PRECISION_H
-
-#include <stdint.h>
-#include "ns3/simulator-config.h"
-
-#if defined (USE_HIGH_PRECISION_DOUBLE)
-#include "high-precision-double.h"
-#elif defined (USE_HIGH_PRECISION_128)
-#include "high-precision-128.h"
-#elif defined (USE_HIGH_PRECISION_CAIRO)
-#include "high-precision-cairo.h"
-#endif
-
-namespace ns3 {
-
-HighPrecision Abs (HighPrecision const &value);
-inline HighPrecision Max (HighPrecision const &a, HighPrecision const &b);
-inline HighPrecision Min (HighPrecision const &a, HighPrecision const &b);
-
-
-inline HighPrecision Max (HighPrecision const &a, HighPrecision const &b)
-{
-  if (a.Compare (b) >= 0)
-    {
-      return a;
-    }
-  else
-    {
-      return b;
-    }
-}
-inline HighPrecision Min (HighPrecision const &a, HighPrecision const &b)
-{
-  if (a.Compare (b) <= 0)
-    {
-      return a;
-    }
-  else
-    {
-      return b;
-    }
-}
-
-} /* namespace ns3 */
-
-#endif /* HIGH_PRECISION_H */
--- a/src/simulator/nstime.h	Mon Aug 23 19:01:11 2010 -0700
+++ b/src/simulator/nstime.h	Tue Aug 24 16:36:41 2010 +0200
@@ -26,7 +26,7 @@
 #include <stdint.h>
 #include <math.h>
 #include <ostream>
-#include "high-precision.h"
+#include "uint64x64.h"
 
 namespace ns3 {
 
@@ -127,7 +127,7 @@
  * 
  * In general, it is thus a really bad idea to try to use time objects of a
  * resolution higher than the global resolution controlled through 
- * TimeBase::SetResolution. If you do need to use picoseconds, it's thus best
+ * Time::SetResolution. If you do need to use picoseconds, it's thus best
  * to switch the global resolution to picoseconds to avoid nasty surprises.
  *
  * Another important issue to keep in mind is that if you increase the
@@ -175,9 +175,24 @@
   inline Time(const Time &o)
     : m_data (o.m_data)
   {}
-  explicit inline Time (const HighPrecision &data)
+  explicit inline Time (const uint64x64_t &data)
     : m_data (data)
   {}
+  explicit inline Time (double v)
+    : m_data (uint64x64_t (v))
+  {}
+  explicit inline Time (int v)
+    : m_data (uint64x64_t (v, 0))
+  {}
+  explicit inline Time (unsigned int v)
+    : m_data (uint64x64_t (v, 0))
+  {}
+  explicit inline Time (long int v)
+    : m_data (uint64x64_t (v, 0))
+  {}
+  explicit inline Time (unsigned long int v)
+    : m_data (uint64x64_t (v, 0))
+  {}
 
   /**
    * \brief String constructor
@@ -195,63 +210,47 @@
    * occur.
    * \param s The string to parse into a Time
    */
-  Time (const std::string & s);
+  explicit Time (const std::string & s);
 
   /**
    * \return true if the time is zero, false otherwise.
    */
   inline bool IsZero (void) const
   {
-    return m_data.Compare (HighPrecision::Zero ()) == 0;
+    return m_data == uint64x64_t ();
   }
   /**
    * \return true if the time is negative or zero, false otherwise.
    */
   inline bool IsNegative (void) const
   {
-    return m_data.Compare (HighPrecision::Zero ()) <= 0;
+    return m_data <= uint64x64_t ();
   }
   /**
    * \return true if the time is positive or zero, false otherwise.
    */
   inline bool IsPositive (void) const
   {
-    return m_data.Compare (HighPrecision::Zero ()) >= 0;
+    return m_data >= uint64x64_t ();
   }
   /**
    * \return true if the time is strictly negative, false otherwise.
    */
   inline bool IsStrictlyNegative (void) const
   {
-    return m_data.Compare (HighPrecision::Zero ()) < 0;
+    return m_data < uint64x64_t ();
   }
   /**
    * \return true if the time is strictly positive, false otherwise.
    */
   inline bool IsStrictlyPositive (void) const
   {
-    return m_data.Compare (HighPrecision::Zero ()) > 0;
+    return m_data > uint64x64_t ();
   }
 
   inline int Compare (const Time &o) const
   {
-    return m_data.Compare (o.m_data);
-  }
-
-  /**
-   * This is really an internal method exported for the needs of
-   * the implementation. Please, Do not try to use this method, ever.
-   *
-   * \return the ns3::HighPrecision object which holds the value
-   *         stored in this instance of Time type.
-   */
-  inline HighPrecision const &GetHighPrecision (void) const
-  {
-    return m_data;
-  }
-  inline HighPrecision *PeekHighPrecision (void)
-  {
-    return &m_data;
+    return (m_data < o.m_data)?-1:(m_data == o.m_data)?0:1;
   }
 
   /**
@@ -309,9 +308,17 @@
    */
   inline int64_t GetTimeStep (void) const
   {
-    int64_t timeValue = m_data.GetInteger ();
+    int64_t timeValue = m_data.GetHigh ();
     return timeValue;
   }
+  inline double GetDouble (void) const
+  {
+    return m_data.GetDouble ();
+  }
+  inline int64_t GetInteger (void) const
+  {
+    return GetTimeStep ();
+  }
 
 
   /**
@@ -342,9 +349,9 @@
     if (info->fromMul)
       {
         value *= info->factor;
-        return Time (HighPrecision (value, false));
+        return Time (uint64x64_t (value, 0));
       }
-    return From (HighPrecision (value, false), timeUnit);
+    return From (uint64x64_t (value, 0), timeUnit);
   }
   /**
    * \param value to convert into a Time object
@@ -355,7 +362,7 @@
    */
   inline static Time FromDouble (double value, enum Unit timeUnit)
   {
-    return From (HighPrecision (value), timeUnit);
+    return From (uint64x64_t (value), timeUnit);
   }
   /**
    * \param time a Time object
@@ -367,7 +374,7 @@
   inline static uint64_t ToInteger (const Time &time, enum Unit timeUnit)
   {
     struct Information *info = PeekInformation (timeUnit);
-    uint64_t v = time.m_data.GetInteger ();
+    uint64_t v = time.m_data.GetHigh ();
     if (info->toMul)
       {
         v *= info->factor;
@@ -396,8 +403,8 @@
     bool toMul;
     bool fromMul;
     uint64_t factor;
-    HighPrecision timeTo;
-    HighPrecision timeFrom;
+    uint64x64_t timeTo;
+    uint64x64_t timeFrom;
   };
   struct Resolution
   {
@@ -414,15 +421,15 @@
   {
     return &(PeekResolution ()->info[timeUnit]);
   }
-  static inline Time From (HighPrecision from, enum Unit timeUnit)
+  static inline Time From (uint64x64_t from, enum Unit timeUnit)
   {
     struct Information *info = PeekInformation (timeUnit);
     // DO NOT REMOVE this temporary variable. It's here
     // to work around a compiler bug in gcc 3.4
-    HighPrecision tmp = from; 
+    uint64x64_t tmp = from; 
     if (info->fromMul)
       {
-        tmp.Mul (info->timeFrom);
+        tmp *= info->timeFrom;
       }
     else
       {
@@ -430,13 +437,13 @@
       }
     return Time (tmp);
   }
-  static inline HighPrecision To (const Time &time, enum Unit timeUnit)
+  static inline uint64x64_t To (const Time &time, enum Unit timeUnit)
   {
     struct Information *info = PeekInformation (timeUnit);
-    HighPrecision tmp = time.GetHighPrecision ();
+    uint64x64_t tmp = time.m_data;
     if (info->toMul)
       {
-        tmp.Mul (info->timeTo);
+        tmp *= info->timeTo;
       }
     else
       {
@@ -448,86 +455,91 @@
   static struct Resolution GetNsResolution (void);
   static void SetResolution (enum Unit unit, struct Resolution *resolution);
 
-  HighPrecision m_data;
+  friend bool operator == (const Time &lhs, const Time &rhs);
+  friend bool operator != (const Time &lhs, const Time &rhs);
+  friend bool operator <= (const Time &lhs, const Time &rhs);
+  friend bool operator >= (const Time &lhs, const Time &rhs);
+  friend bool operator < (const Time &lhs, const Time &rhs);
+  friend bool operator > (const Time &lhs, const Time &rhs);
+  friend Time operator + (const Time &lhs, const Time &rhs);
+  friend Time operator - (const Time &lhs, const Time &rhs);
+  friend Time operator * (const Time &lhs, const Time &rhs);
+  friend Time operator / (const Time &lhs, const Time &rhs);
+  friend Time &operator += (Time &lhs, const Time &rhs);
+  friend Time &operator -= (Time &lhs, const Time &rhs);
+  friend Time &operator *= (Time &lhs, const Time &rhs);
+  friend Time &operator /= (Time &lhs, const Time &rhs);
+  friend Time Abs (const Time &time);
+  friend Time Max (const Time &ta, const Time &tb);
+  friend Time Min (const Time &ta, const Time &tb);
+
+  uint64x64_t m_data;
 };
 
 inline bool
-operator == (Time const &lhs, Time const &rhs)
+operator == (const Time &lhs, const Time &rhs)
 {
-  return lhs.Compare (rhs) == 0;
+  return lhs.m_data == rhs.m_data;
 }
 inline bool
-operator != (Time const &lhs, Time const &rhs)
+operator != (const Time &lhs, const Time &rhs)
 {
-  return lhs.Compare (rhs) != 0;
+  return lhs.m_data != rhs.m_data;
 }
 inline bool
-operator <= (Time const &lhs, Time const &rhs)
+operator <= (const Time &lhs, const Time &rhs)
 {
-  return lhs.Compare (rhs) <= 0;
+  return lhs.m_data <= rhs.m_data;
 }
 inline bool
-operator >= (Time const &lhs, Time const &rhs)
+operator >= (const Time &lhs, const Time &rhs)
 {
-  return lhs.Compare (rhs) >= 0;
+  return lhs.m_data >= rhs.m_data;
 }
 inline bool
-operator < (Time const &lhs, Time const &rhs)
+operator < (const Time &lhs, const Time &rhs)
 {
-  return lhs.Compare (rhs) < 0;
+  return lhs.m_data < rhs.m_data;
 }
 inline bool
-operator > (Time const &lhs, Time const &rhs)
+operator > (const Time &lhs, const Time &rhs)
 {
-  return lhs.Compare (rhs) > 0;
+  return lhs.m_data > rhs.m_data;
 }
-inline Time operator + (Time const &lhs, Time const &rhs)
+inline Time operator + (const Time &lhs, const Time &rhs)
 {
-  HighPrecision retval = lhs.GetHighPrecision ();
-  retval.Add (rhs.GetHighPrecision ());
-  return Time (retval);
+  return Time (lhs.m_data + rhs.m_data);
 }
-inline Time operator - (Time const &lhs, Time const &rhs)
+inline Time operator - (const Time &lhs, const Time &rhs)
 {
-  HighPrecision retval = lhs.GetHighPrecision ();
-  retval.Sub (rhs.GetHighPrecision ());
-  return Time (retval);
+  return Time (lhs.m_data - rhs.m_data);
 }
-inline Time operator * (Time const &lhs, Time const &rhs)
+inline Time operator * (const Time &lhs, const Time &rhs)
 {
-  HighPrecision retval = lhs.GetHighPrecision ();
-  retval.Mul (rhs.GetHighPrecision ());
-  return Time (retval);
+  return Time (lhs.m_data * rhs.m_data);
 }
-inline Time operator / (Time const &lhs, Time const &rhs)
+inline Time operator / (const Time &lhs, const Time &rhs)
 {
-  NS_ASSERT (rhs.GetHighPrecision ().GetDouble () != 0);
-  HighPrecision retval = lhs.GetHighPrecision ();
-  retval.Div (rhs.GetHighPrecision ());
-  return Time (retval);
+  return Time (lhs.m_data / rhs.m_data);
 }
-inline Time &operator += (Time &lhs, Time const &rhs)
+inline Time &operator += (Time &lhs, const Time &rhs)
 {
-  HighPrecision *lhsv = lhs.PeekHighPrecision ();
-  lhsv->Add (rhs.GetHighPrecision ());
+  lhs.m_data += rhs.m_data;
   return lhs;
 }
-inline Time &operator -= (Time &lhs, Time const &rhs)
+inline Time &operator -= (Time &lhs, const Time &rhs)
 {
-  HighPrecision *lhsv = lhs.PeekHighPrecision ();
-  lhsv->Sub (rhs.GetHighPrecision ());
+  lhs.m_data -= rhs.m_data;
   return lhs;
 }
-inline Time &operator *= (Time &lhs, Time const &rhs)
+inline Time &operator *= (Time &lhs, const Time &rhs)
 {
-  HighPrecision *lhsv = lhs.PeekHighPrecision ();
-  lhsv->Mul (rhs.GetHighPrecision ());
+  lhs.m_data *= rhs.m_data;
   return lhs;
 }
-inline Time &operator /= (Time &lhs, Time const &rhs)
+inline Time &operator /= (Time &lhs, const Time &rhs)
 {
-  HighPrecision *lhsv = lhs.PeekHighPrecision ();
-  lhsv->Div (rhs.GetHighPrecision ());
+  lhs.m_data /= rhs.m_data;
   return lhs;
 }
 
@@ -538,9 +550,9 @@
  * \param time the input value
  * \returns the absolute value of the input value.
  */
-inline Time Abs (Time const &time)
+inline Time Abs (const Time &time)
 {
-  return Time (Abs (time.GetHighPrecision ()));
+  return Time ((time.m_data < uint64x64_t (0))?-time.m_data:time.m_data);
 }
 /**
  * \anchor ns3-Time-Max
@@ -549,11 +561,9 @@
  * \param tb the seconds value
  * \returns the max of the two input values.
  */
-inline Time Max (Time const &ta, Time const &tb)
+inline Time Max (const Time &ta, const Time &tb)
 {
-  HighPrecision a = ta.GetHighPrecision ();
-  HighPrecision b = tb.GetHighPrecision ();
-  return Time (Max (a, b));
+  return Time ((ta.m_data < tb.m_data)?tb:ta);
 }
 /**
  * \anchor ns3-Time-Min
@@ -562,11 +572,9 @@
  * \param tb the seconds value
  * \returns the min of the two input values.
  */
-inline Time Min (Time const &ta, Time const &tb)
+inline Time Min (const Time &ta, const Time &tb)
 {
-  HighPrecision a = ta.GetHighPrecision ();
-  HighPrecision b = tb.GetHighPrecision ();
-  return Time (Min (a, b));
+  return Time ((ta.m_data > tb.m_data)?tb:ta);
 }
 
 
@@ -662,45 +670,10 @@
 // internal function not publicly documented
 inline Time TimeStep (uint64_t ts)
 {
-  return Time (HighPrecision (ts, false));
+  return Time (uint64x64_t (ts, 0));
 }
 
-class Scalar
-{
-public:
-  inline Scalar ()
-    : m_v (0.0)
-  {}
-  explicit inline Scalar (double v)
-    : m_v (v)
-  {}
-  explicit inline Scalar (uint32_t v)
-    : m_v (v)
-  {}
-  explicit inline Scalar (int32_t v)
-    : m_v (v)
-  {}
-  explicit inline Scalar (uint64_t v)
-    : m_v (v)
-  {}
-  explicit inline Scalar (int64_t v)
-    : m_v (v)
-  {}
-  inline Scalar (Time t)
-    : m_v (t.GetHighPrecision ().GetDouble ())
-  {}
-  inline operator Time ()
-  {
-    return Time (HighPrecision (m_v));
-  }
-  inline double GetDouble (void) const
-  {
-    return m_v;
-  }
-private:
-  double m_v;
-};
-
+typedef Time Scalar;
 typedef Time TimeInvert;
 typedef Time TimeSquare;
 
--- a/src/simulator/time.cc	Mon Aug 23 19:01:11 2010 -0700
+++ b/src/simulator/time.cc	Tue Aug 24 16:36:41 2010 +0200
@@ -26,14 +26,11 @@
 #include "ns3/string.h"
 #include "ns3/object.h"
 #include "ns3/config.h"
-#include "ns3/log.h"
 #include <math.h>
 #include <sstream>
 
 namespace ns3 {
 
-NS_LOG_COMPONENT_DEFINE("Time");
-
 Time::Time (const std::string& s)
 {
   std::string::size_type n = s.find_first_not_of ("0123456789.");
@@ -100,7 +97,6 @@
 void 
 Time::SetResolution (enum Unit unit, struct Resolution *resolution)
 {
-  NS_LOG_FUNCTION (unit << resolution);
   int8_t power [LAST] = {15, 12, 9, 6, 3, 0};
   for (int i = 0; i < Time::LAST; i++)
     {
@@ -110,30 +106,26 @@
       info->factor = factor;
       if (shift == 0)
 	{
-	  info->timeFrom = HighPrecision (1, false);
-	  info->timeTo = HighPrecision (1, false);
+	  info->timeFrom = uint64x64_t (1, 0);
+	  info->timeTo = uint64x64_t (1, 0);
 	  info->toMul = true;
 	  info->fromMul = true;
 	}
       else if (shift > 0)
 	{
-	  info->timeFrom = HighPrecision (factor, false);
-	  info->timeTo = HighPrecision::Invert (factor);
+	  info->timeFrom = uint64x64_t (factor, 0);
+	  info->timeTo = uint64x64_t::Invert (factor);
 	  info->toMul = false;
 	  info->fromMul = true;
 	}
       else
 	{
 	  NS_ASSERT (shift < 0);
-	  info->timeFrom = HighPrecision::Invert (factor);
-	  info->timeTo = HighPrecision (factor, false);
+	  info->timeFrom = uint64x64_t::Invert (factor);
+	  info->timeTo = uint64x64_t (factor, 0);
 	  info->toMul = true;
 	  info->fromMul = false;
 	}
-      NS_LOG_DEBUG ("i=" << i << 
-                    " shift=" << shift << 
-                    " from=" << info->timeFrom <<
-                    " to=" << info->timeTo);
     }
   resolution->unit = unit;
 }
@@ -173,7 +165,7 @@
       unit = "unreachable";
       break;
     }
-  uint64_t v = Time::ToInteger (time, Time::GetResolution ());
+  double v = Time::ToDouble (time, Time::GetResolution ());
   os << v << unit;
   return os;
 }
@@ -208,7 +200,9 @@
 
 bool Bug863TestCase::DoRun (void)
 {
-  Scalar result = Scalar (0.9) / Scalar (1.0);
+  Scalar a = Scalar (0.9);
+  Scalar b = Scalar (1.0);
+  Scalar result = a / b;
   NS_TEST_ASSERT_MSG_EQ ((result == Scalar (0.9)), true, "Invalid arithmetic result");
   return false;
 }
@@ -260,44 +254,6 @@
   Time::SetResolution (m_originalResolution);
 }
 
-class ArithTestCase : public TestCase
-{
-public:
-  ArithTestCase ();
-private:
-  virtual bool DoRun (void);
-};
-
-ArithTestCase::ArithTestCase ()
-  : TestCase ("check arithmetic operators")
-{
-}
-bool 
-ArithTestCase::DoRun (void)
-{
-  Time a, b, c;
-  c = a + b;
-  c = a * b;
-  c = a / Seconds (1.0);
-  c = a - b;
-  c += a;
-  c -= a;
-  c /= Seconds (1.0);
-  c *= a;
-  bool x;
-  x = a < b;
-  x = a > b;
-  x = a <= b;
-  x = a >= b;
-  x = a == b;
-  x = a != b;
-  //a = 1.0;
-  //a = 1;
-  return false;
-}
-
-
-
 static class TimeTestSuite : public TestSuite
 {
 public:
@@ -306,7 +262,6 @@
   {
     AddTestCase (new Bug863TestCase ());
     AddTestCase (new TimeSimpleTestCase (Time::US));
-    AddTestCase (new ArithTestCase ());
   }
 } g_timeTestSuite;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64-128.cc	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,138 @@
+#include "uint64x64-128.h"
+#include "ns3/abort.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+#define OUTPUT_SIGN(sa,sb,ua,ub)					\
+  ({bool negA, negB;							\
+    negA = sa < 0;							\
+    negB = sb < 0;							\
+    ua = negA?-sa:sa;							\
+    ub = negB?-sb:sb;							\
+    (negA && !negB) || (!negA && negB);})
+
+
+#define MASK_LO ((((int128_t)1)<<64)-1)
+#define MASK_HI (~MASK_LO)
+
+void
+uint64x64_t::Mul (uint64x64_t const &o)
+{
+  bool negResult;
+  uint128_t a, b;
+  negResult = OUTPUT_SIGN (_v, o._v, a, b);
+  int128_t result = Umul (a, b);
+  // add the sign to the result
+  result = negResult ? -result : result;
+  _v = result;
+}
+
+uint128_t
+uint64x64_t::Umul (uint128_t a, uint128_t b)
+{
+  uint128_t aL = a & MASK_LO;
+  uint128_t bL = b & MASK_LO;
+  uint128_t aH = (a >> 64) & MASK_LO;
+  uint128_t bH = (b >> 64) & MASK_LO;
+
+  uint128_t result;
+  uint128_t hiPart,loPart,midPart;
+
+  // Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
+  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
+  // get the low part a.l b.l
+  // multiply the fractional part
+  loPart = aL * bL;
+  // compute the middle part 2^64*(a.h b.l+b.h a.l)
+  midPart = aL * bH + aH * bL;
+  // truncate the low part
+  result = (loPart >> 64) + (midPart & MASK_LO);
+  // compute the high part 2^128 a.h b.h
+  hiPart = aH * bH;
+  // truncate the high part and only use the low part
+  result |= ((hiPart & MASK_LO) << 64) + (midPart & MASK_HI);
+  // if the high part is not zero, put a warning
+  NS_ABORT_MSG_IF ((hiPart & MASK_HI) != 0,
+		   "High precision 128 bits multiplication error: multiplication overflow.");
+  return result;
+}
+void
+uint64x64_t::Div (uint64x64_t const &o)
+{
+  bool negResult;
+  uint128_t a, b;
+  negResult = OUTPUT_SIGN (_v, o._v, a, b);  
+  int128_t result = Divu (a, b);
+  result = negResult ? -result:result;
+  _v = result;
+}
+
+uint128_t
+uint64x64_t::Divu (uint128_t a, uint128_t b)
+{
+  uint128_t quo = a / b;
+  uint128_t rem = (a % b);
+  uint128_t result = quo << 64;
+  // Now, manage the remainder
+  uint128_t tmp = rem >> 64;
+  uint128_t div;
+  if (tmp == 0)
+    {
+      rem = rem << 64;
+      div = b;
+    }
+  else
+    {
+      rem = rem;
+      div = b >> 64;
+    }
+  quo = rem / div;
+  result = result + quo;
+  return result;
+}
+
+void 
+uint64x64_t::MulByInvert (const uint64x64_t &o)
+{
+  bool negResult = _v < 0;
+  uint128_t a = negResult?-_v:_v;
+  uint128_t result = UmulByInvert (a, o._v);
+
+  _v = negResult?-result:result;
+}
+uint128_t
+uint64x64_t::UmulByInvert (uint128_t a, uint128_t b)
+{
+  uint128_t result, ah, bh, al, bl;
+  uint128_t hi, mid;
+  ah = a >> 64;
+  bh = b >> 64;
+  al = a & MASK_LO;
+  bl = b & MASK_LO;
+  hi = ah * bh;
+  mid = ah * bl + al * bh;
+  mid >>= 64;
+  result = ah * bh + mid;
+  return result;
+}
+uint64x64_t 
+uint64x64_t::Invert (uint64_t v)
+{
+  NS_ASSERT (v > 1);
+  uint128_t a;
+  a = 1;
+  a <<= 64;
+  uint64x64_t result;
+  result._v = Divu (a, v);
+  uint64x64_t tmp = uint64x64_t (v, false);
+  tmp.MulByInvert (result);
+  if (tmp.GetHigh () != 1)
+    {
+      result._v += 1;
+    }
+  return result;
+}
+
+} // namespace ns3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64-128.h	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,197 @@
+#ifndef UINT64X64_128_H
+#define UINT64X64_128_H
+
+#include "ns3/simulator-config.h"
+#include <stdint.h>
+#include <math.h>
+
+#if defined(HAVE___UINT128_T) and !defined(HAVE_UINT128_T)
+typedef __uint128_t uint128_t;
+typedef __int128_t int128_t;
+#endif
+
+namespace ns3 {
+
+#define HP128_MAX_64 18446744073709551615.0
+#define HP128_MASK_LO ((((int128_t)1)<<64)-1)
+
+class uint64x64_t
+{
+public:
+  inline uint64x64_t ()
+    : _v (0)
+  {}
+  explicit inline uint64x64_t (double value)
+  {
+    bool is_negative = value < 0;
+    value = is_negative?-value:value;
+    double hi = floor (value);
+    double lo = (value - hi) * HP128_MAX_64;
+    _v = (int128_t)hi;
+    _v <<= 64;
+    _v += (int128_t)lo;
+    _v = is_negative?-_v:_v;
+  }
+  explicit inline uint64x64_t (int v)
+    : _v (v)
+  {
+    _v <<= 64;
+  }
+  explicit inline uint64x64_t (long int v)
+    : _v (v) 
+  {
+    _v <<= 64;
+  }
+  explicit inline uint64x64_t (long long int v)
+    : _v (v) 
+  {
+    _v <<= 64;
+  }
+  explicit inline uint64x64_t (int64_t hi, uint64_t lo)
+  {
+    bool is_negative = hi<0;
+    _v = is_negative?-hi:hi;
+    _v <<= 64;
+    _v += lo;
+    _v = is_negative?-_v:_v;
+  }
+
+  inline uint64x64_t (const uint64x64_t &o)
+    : _v (o._v) {}
+  inline uint64x64_t &operator = (const uint64x64_t &o)
+    {
+      _v = o._v;
+      return *this;
+    }
+
+  inline double GetDouble (void) const
+  {
+    bool is_negative = _v < 0;
+    uint128_t value = is_negative ? -_v:_v;
+    uint64_t hi = value >> 64;
+    uint64_t lo = value;
+    double flo = lo;
+    flo /= HP128_MAX_64;
+    double retval = hi;
+    retval += flo;
+    retval = is_negative ? -retval : retval;
+    return retval;
+  }
+  inline int64_t GetHigh (void) const
+  {
+    bool negative = _v < 0;
+    int128_t v = negative?-_v:_v;
+    v >>= 64;
+    int64_t retval = v;
+    return negative?-retval:retval;
+  }
+  inline uint64_t GetLow (void) const
+  {
+    bool negative = _v < 0;
+    int128_t v = negative?-_v:_v;
+    int128_t low = v & HP128_MASK_LO;
+    uint64_t retval = low;
+    return retval;
+  }
+#undef HP128_MAX_64
+#undef HP128_MASK_LO
+
+  void MulByInvert (const uint64x64_t &o);
+
+  static uint64x64_t Invert (uint64_t v);
+
+private:
+  friend bool operator == (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator != (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator <= (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator >= (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator < (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator > (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator += (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator -= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator *= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator /= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator + (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator - (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator * (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator / (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator + (const uint64x64_t &lhs);
+  friend uint64x64_t operator - (const uint64x64_t &lhs);
+  friend uint64x64_t operator ! (const uint64x64_t &lhs);
+  void Mul (const uint64x64_t &o);
+  void Div (const uint64x64_t &o);
+  static uint128_t UmulByInvert (uint128_t a, uint128_t b);
+  static uint128_t Umul (uint128_t a, uint128_t b);
+  static uint128_t Divu (uint128_t a, uint128_t b);
+  inline uint64x64_t (int128_t v)
+    : _v (v) {}
+
+  int128_t _v;
+};
+
+inline bool operator == (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v == rhs._v;
+}
+
+inline bool operator != (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v != rhs._v;
+}
+
+inline bool operator < (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v < rhs._v;
+}
+inline bool operator <= (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v <= rhs._v;
+}
+
+inline bool operator >= (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v >= rhs._v;
+}
+inline bool operator > (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v > rhs._v;
+}
+inline uint64x64_t &operator += (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  lhs._v += rhs._v;
+  return lhs;
+}
+inline uint64x64_t &operator -= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  lhs._v -= rhs._v;
+  return lhs;
+}
+inline uint64x64_t &operator *= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  lhs.Mul (rhs);
+  return lhs;
+}
+inline uint64x64_t &operator /= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  lhs.Div (rhs);
+  return lhs;
+}
+
+inline uint64x64_t operator + (const uint64x64_t &lhs)
+{
+  return lhs;
+}
+
+inline uint64x64_t operator - (const uint64x64_t &lhs)
+{
+  return uint64x64_t (-lhs._v);
+}
+
+inline uint64x64_t operator ! (const uint64x64_t &lhs)
+{
+  return uint64x64_t (!lhs._v);
+}
+
+} // namespace ns3
+
+#endif /* UINT64X64_128_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64-cairo.cc	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,162 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "uint64x64-cairo.h"
+#include "ns3/test.h"
+#include "ns3/abort.h"
+#include "ns3/assert.h"
+#include <math.h>
+#include <iostream>
+
+namespace ns3 {
+
+#define OUTPUT_SIGN(sa,sb,ua,ub)                                        \
+  ({bool negA, negB;                                                    \
+  negA = _cairo_int128_negative (sa);                                   \
+  negB = _cairo_int128_negative (sb);                                   \
+  ua = _cairo_int128_to_uint128 (sa);                                   \
+  ub = _cairo_int128_to_uint128 (sb);                                   \
+  ua = negA ? _cairo_uint128_negate (ua) : ua;                          \
+  ub = negB ? _cairo_uint128_negate (ub) : ub;                          \
+  (negA && !negB) || (!negA && negB);})
+
+void
+uint64x64_t::Mul (uint64x64_t const &o)
+{
+  cairo_uint128_t a, b, result;
+  bool sign = OUTPUT_SIGN (_v, o._v, a, b);
+  result = Umul (a, b);
+  _v = sign ? _cairo_uint128_negate (result) : result;
+}
+
+/**
+ * this function multiplies two 128 bits fractions considering
+ * the high 64 bits as the integer part and the low 64 bits
+ * as the fractional part. It takes into account the sign
+ * of the operands to produce a signed 128 bits result.
+ */
+cairo_uint128_t
+uint64x64_t::Umul (cairo_uint128_t a, cairo_uint128_t b)
+{
+  cairo_uint128_t result;
+  cairo_uint128_t hiPart,loPart,midPart;
+
+  // Multiplying (a.h 2^64 + a.l) x (b.h 2^64 + b.l) =
+  //			2^128 a.h b.h + 2^64*(a.h b.l+b.h a.l) + a.l b.l
+  // get the low part a.l b.l
+  // multiply the fractional part
+  loPart = _cairo_uint64x64_128_mul (a.lo, b.lo);
+  // compute the middle part 2^64*(a.h b.l+b.h a.l)
+  midPart = _cairo_uint128_add (_cairo_uint64x64_128_mul (a.lo, b.hi),
+                                _cairo_uint64x64_128_mul (a.hi, b.lo));
+  // truncate the low part
+  result.lo = _cairo_uint64_add (loPart.hi,midPart.lo);
+  // compute the high part 2^128 a.h b.h
+  hiPart = _cairo_uint64x64_128_mul (a.hi, b.hi);
+  // truncate the high part and only use the low part
+  result.hi = _cairo_uint64_add (hiPart.lo,midPart.hi);
+  // if the high part is not zero, put a warning
+  NS_ABORT_MSG_IF (hiPart.hi != 0,
+                   "High precision 128 bits multiplication error: multiplication overflow.");
+  return result;
+}
+
+void
+uint64x64_t::Div (uint64x64_t const &o)
+{
+  cairo_uint128_t a, b, result;
+  bool sign = OUTPUT_SIGN (_v, o._v, a, b);
+  result = Udiv (a, b);
+  _v = sign ? _cairo_uint128_negate (result) : result;
+}
+
+cairo_uint128_t
+uint64x64_t::Udiv (cairo_uint128_t a, cairo_uint128_t b)
+{
+  cairo_uquorem128_t qr = _cairo_uint128_divrem (a, b);
+  cairo_uint128_t result = _cairo_uint128_lsl (qr.quo, 64);
+  // Now, manage the remainder
+  cairo_uint128_t tmp = _cairo_uint128_rsl (qr.rem, 64);
+  cairo_uint128_t zero = _cairo_uint64_to_uint128 (0);
+  cairo_uint128_t rem, div;
+  if (_cairo_uint128_eq (tmp, zero))
+    {
+      rem = _cairo_uint128_lsl (qr.rem, 64);
+      div = b;
+    }
+  else
+    {
+      rem = qr.rem;
+      div = _cairo_uint128_rsl (b, 64);
+    }
+  qr = _cairo_uint128_divrem (rem, div);
+  result = _cairo_uint128_add (result, qr.quo);
+  return result;
+}
+
+void 
+uint64x64_t::MulByInvert (const uint64x64_t &o)
+{
+  bool negResult = _cairo_int128_negative (_v);
+  cairo_uint128_t a = negResult?_cairo_int128_negate(_v):_v;
+  cairo_uint128_t result = UmulByInvert (a, o._v);
+
+  _v = negResult?_cairo_int128_negate(result):result;
+}
+cairo_uint128_t
+uint64x64_t::UmulByInvert (cairo_uint128_t a, cairo_uint128_t b)
+{
+  cairo_uint128_t result;
+  cairo_uint128_t hi, mid;
+  hi = _cairo_uint64x64_128_mul (a.hi, b.hi);
+  mid = _cairo_uint128_add (_cairo_uint64x64_128_mul (a.hi, b.lo),
+                           _cairo_uint64x64_128_mul (a.lo, b.hi));
+  mid.lo = mid.hi;
+  mid.hi = 0;
+  result = _cairo_uint128_add (hi,mid);
+  return result;
+}
+uint64x64_t 
+uint64x64_t::Invert (uint64_t v)
+{
+  NS_ASSERT (v > 1);
+  cairo_uint128_t a, factor;
+  a.hi = 1;
+  a.lo = 0;
+  factor.hi = 0;
+  factor.lo = v;
+  uint64x64_t result;
+  result._v = Udiv (a, factor);
+  uint64x64_t tmp = uint64x64_t (v, 0);
+  tmp.MulByInvert (result);
+  if (tmp.GetHigh () != 1)
+    {
+      cairo_uint128_t one = {1, 0};
+      result._v = _cairo_uint128_add (result._v, one);
+    }
+  return result;
+}
+
+
+} // namespace ns3
+
+// include directly to allow optimizations within the compilation unit.
+extern "C" {
+#include "cairo-wideint.c"
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64-cairo.h	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,278 @@
+#ifndef UINT64X64_CAIRO_H
+#define UINT64X64_CAIRO_H
+
+#include <stdint.h>
+#include <math.h>
+#include "cairo-wideint-private.h"
+
+#ifdef __i386__
+#define UINT64x64_CAIRO_ASM 1
+#endif
+
+namespace ns3 {
+
+class uint64x64_t
+{
+public:
+  inline uint64x64_t ()
+  {
+    _v.hi = 0;
+    _v.lo = 0;
+  }
+  explicit inline uint64x64_t (double value)
+  {
+#define HPCAIRO_MAX_64 18446744073709551615.0
+    double fhi = floor (value);
+    int64_t hi = fhi;
+    uint64_t lo = (uint64_t) ((value - fhi) * HPCAIRO_MAX_64);
+    _v.hi = hi;
+    _v.lo = lo;
+#undef HPCAIRO_MAX_64
+  }
+  explicit inline uint64x64_t (int v)
+  {
+    _v.hi = v;
+    _v.lo = 0;
+  }
+  explicit inline uint64x64_t (long int v)
+  {
+    _v.hi = v;
+    _v.lo = 0;
+  }
+  explicit inline uint64x64_t (long long int v)
+  {
+    _v.hi = v;
+    _v.lo = 0;
+  }
+  explicit inline uint64x64_t (int64_t hi, uint64_t lo)
+  {
+    _v.hi = hi;
+    _v.lo = lo;
+  }
+
+  inline uint64x64_t (const uint64x64_t &o)
+    : _v (o._v) {}
+  inline uint64x64_t &operator = (const uint64x64_t &o)
+    {
+      _v = o._v;
+      return *this;
+    }
+
+  inline double GetDouble (void) const
+  {
+#define HPCAIRO_MAX_64 18446744073709551615.0
+    bool is_negative = IsNegative ();
+    cairo_int128_t value = is_negative ? _cairo_int128_negate (_v) : _v;
+    double flo = value.lo;
+    flo /= HPCAIRO_MAX_64;
+    double retval = value.hi;
+    retval += flo;
+    retval = is_negative ? -retval: retval;
+    return retval;
+#undef HPCAIRO_MAX_64
+  }
+  inline int64_t GetHigh (void) const
+  {
+    return (int64_t)_v.hi;
+  }
+  inline uint64_t GetLow (void) const
+  {
+    return _v.lo;
+  }
+
+  void MulByInvert (const uint64x64_t &o);
+
+  static uint64x64_t Invert (uint64_t v);
+
+private:
+  friend bool operator == (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator != (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator <= (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator >= (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator < (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator > (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator += (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator -= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator *= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator /= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator + (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator - (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator * (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator / (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator + (const uint64x64_t &lhs);
+  friend uint64x64_t operator - (const uint64x64_t &lhs);
+  friend uint64x64_t operator ! (const uint64x64_t &lhs);
+  void Mul (const uint64x64_t &o);
+  void Div (const uint64x64_t &o);
+  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
+  {
+    int64_t hi = _v.hi;
+    return hi < 0;
+  }
+  inline void Negate (void)
+  {
+    _v.lo = ~_v.lo;
+    _v.hi = ~_v.hi;
+    if (++_v.lo == 0)
+      {
+	++_v.hi;
+      }
+  }
+
+  cairo_int128_t _v;
+};
+
+#if defined(UINT64x64_CAIRO_ASM)
+#define xCMP_ls "jl"
+#define xCMP_le "jle"
+#define COMPARE(a,b,op)				\
+  ({						\
+    int status;					\
+    asm ("mov 0(%1),%%eax\n\t"			\
+	 "add 0(%2),%%eax\n\t"			\
+	 "mov 4(%1),%%eax\n\t"			\
+	 "adc 4(%2),%%eax\n\t"			\
+	 "mov 8(%1),%%eax\n\t"			\
+	 "adc 8(%2),%%eax\n\t"			\
+	 "mov 12(%1),%%eax\n\t"			\
+	 "adc 12(%2),%%eax\n\t"			\
+	 x##op " 1f\n\t"			\
+	 "mov $0,%0\n\t"				\
+	 "ja 2f\n"				\
+	 "1:\tmov $1,%0\n\t"			\
+	 "2:"					\
+	 : "=r" (status)			\
+	 : "r" (&a._v), "r" (&b._v)		\
+	 : "%eax", "cc");			\
+    bool retval = status == 1;			\
+    retval;					\
+  })
+#else
+#define xCMP_ls(a) (((int64_t)(a)._v.hi) < 0)
+#define xCMP_le(a) ((((int64_t)(a)._v.hi) < 0) || ((a)._v.hi == 0 && (a)._v.lo == 0))
+#define COMPARE(a,b,op)							\
+  ({									\
+    uint64x64_t tmp = a;						\
+    tmp -= b;								\
+    bool result = x##op(tmp);						\
+    result;								\
+  }) 
+#endif
+
+inline bool operator == (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v.hi == rhs._v.hi && lhs._v.lo == lhs._v.lo;
+}
+
+inline bool operator != (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return ! (lhs == rhs);
+}
+
+inline bool operator < (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return COMPARE(lhs,rhs,CMP_ls);
+}
+inline bool operator <= (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return COMPARE(lhs,rhs,CMP_le);
+}
+
+inline bool operator >= (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return !(lhs < rhs);
+}
+inline bool operator > (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return !(lhs <= rhs);
+}
+inline uint64x64_t &operator += (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+#if UINT64x64_CAIRO_ASM
+  asm ("mov 0(%0),%%eax\n\t"
+       "add 0(%1),%%eax\n\t"
+       "mov %%eax,0(%0)\n\t"
+       "mov 4(%0),%%eax\n\t"
+       "adc 4(%1),%%eax\n\t"
+       "mov %%eax,4(%0)\n\t"
+       "mov 8(%0),%%eax\n\t"
+       "adc 8(%1),%%eax\n\t"
+       "mov %%eax,8(%0)\n\t"
+       "mov 12(%0),%%eax\n\t"
+       "adc 12(%1),%%eax\n\t"
+       "mov %%eax,12(%0)\n\t"
+       : 
+       : "r" (&lhs._v), "r" (&rhs._v) 
+       : "%eax", "cc");
+#else
+  lhs._v.hi += rhs._v.hi;
+  lhs._v.lo += rhs._v.lo;
+  if (lhs._v.lo < rhs._v.lo)
+    {
+      lhs._v.hi++;
+    }
+#endif
+  return lhs;
+}
+inline uint64x64_t &operator -= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+#if UINT64x64_CAIRO_ASM
+  asm ("mov 0(%0),%%eax\n\t"
+       "sub 0(%1),%%eax\n\t"
+       "mov %%eax,0(%0)\n\t"
+       "mov 4(%0),%%eax\n\t"
+       "sbb 4(%1),%%eax\n\t"
+       "mov %%eax,4(%0)\n\t"
+       "mov 8(%0),%%eax\n\t"
+       "sbb 8(%1),%%eax\n\t"
+       "mov %%eax,8(%0)\n\t"
+       "mov 12(%0),%%eax\n\t"
+       "sbb 12(%1),%%eax\n\t"
+       "mov %%eax,12(%0)\n\t"
+       : 
+       : "r" (&lhs._v), "r" (&rhs._v) 
+       : "%eax", "cc");
+#else
+  lhs._v.hi -= rhs._v.hi;
+  lhs._v.lo -= rhs._v.lo;
+  if (lhs._v.lo > rhs._v.lo)
+    {
+      lhs._v.hi--;
+    }
+#endif
+  return lhs;
+}
+inline uint64x64_t &operator *= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  lhs.Mul (rhs);
+  return lhs;
+}
+inline uint64x64_t &operator /= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  lhs.Div (rhs);
+  return lhs;
+}
+
+inline uint64x64_t operator + (const uint64x64_t &lhs)
+{
+  return lhs;
+}
+
+inline uint64x64_t operator - (const uint64x64_t &lhs)
+{
+  uint64x64_t tmp = lhs;
+  tmp.Negate ();
+  return tmp;
+}
+
+inline uint64x64_t operator ! (const uint64x64_t &lhs)
+{
+  return (lhs._v.hi == 0 && lhs._v.lo == 0)?uint64x64_t (1, 0):uint64x64_t ();
+}
+
+} // namespace ns3
+
+#endif /* UINT64X64_CAIRO_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64-double.h	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,153 @@
+#ifndef UINT64X64_DOUBLE_H
+#define UINT64X64_DOUBLE_H
+
+#include <iostream>
+#include <math.h>
+
+namespace ns3 {
+
+class uint64x64_t
+{
+public:
+  inline uint64x64_t ()
+    : _v (0) {}
+  explicit inline uint64x64_t (double v)
+    : _v (v) {}
+  explicit inline uint64x64_t (int v)
+    : _v (v) {}
+  explicit inline uint64x64_t (long int v)
+    : _v (v) {}
+  explicit inline uint64x64_t (long long int v)
+    : _v (v) {}
+  inline uint64x64_t (int64_t hi, uint64_t lo)
+    : _v (hi) {/* XXX */}
+
+  inline uint64x64_t (const uint64x64_t &o)
+    : _v (o._v) {}
+  inline uint64x64_t &operator = (const uint64x64_t &o)
+    {
+      _v = o._v;
+      return *this;
+    }
+
+  inline double GetDouble (void) const
+  {
+    return _v;
+  }
+  inline int64_t GetHigh (void) const
+  {
+    return (int64_t)floor (_v);
+  }
+  inline uint64_t GetLow (void) const
+  {
+    // XXX
+    return 0;
+  }
+
+  inline void MulByInvert (const uint64x64_t &o)
+  {
+    _v *= o._v;
+  }
+
+  static inline uint64x64_t Invert (uint64_t v)
+  {
+    double d = v;
+    return uint64x64_t (1/d);
+  }
+
+private:
+  friend bool operator == (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator != (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator <= (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator >= (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator < (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend bool operator > (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator += (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator -= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator *= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t &operator /= (uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator + (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator - (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator * (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator / (const uint64x64_t &lhs, const uint64x64_t &rhs);
+  friend uint64x64_t operator + (const uint64x64_t &lhs);
+  friend uint64x64_t operator - (const uint64x64_t &lhs);
+  friend uint64x64_t operator ! (const uint64x64_t &lhs);
+
+  double _v;
+};
+
+inline bool operator == (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v == rhs._v;
+}
+
+inline bool operator != (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v != rhs._v;
+}
+
+inline bool operator <= (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v <= rhs._v;
+}
+
+inline bool operator >= (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v >= rhs._v;
+}
+inline bool operator < (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v < rhs._v;
+}
+inline bool operator > (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  return lhs._v > rhs._v;
+}
+inline uint64x64_t &operator += (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  double tmp = lhs._v;
+  tmp += rhs._v;
+  lhs = uint64x64_t (tmp);
+  return lhs;
+}
+inline uint64x64_t &operator -= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  double tmp = lhs._v;
+  tmp -= rhs._v;
+  lhs = uint64x64_t (tmp);
+  return lhs;
+}
+inline uint64x64_t &operator *= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  double tmp = lhs._v;
+  tmp *= rhs._v;
+  lhs = uint64x64_t (tmp);
+  return lhs;
+}
+inline uint64x64_t &operator /= (uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  double tmp = lhs._v;
+  tmp /= rhs._v;
+  lhs = uint64x64_t (tmp);
+  return lhs;
+}
+
+inline uint64x64_t operator + (const uint64x64_t &lhs)
+{
+  return lhs;
+}
+
+inline uint64x64_t operator - (const uint64x64_t &lhs)
+{
+  return uint64x64_t (-lhs._v);
+}
+
+inline uint64x64_t operator ! (const uint64x64_t &lhs)
+{
+  return uint64x64_t (!lhs._v);
+}
+
+} // namespace ns3
+
+#endif /* UINT64X64_DOUBLE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64.cc	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,460 @@
+#include "uint64x64.h"
+#include <stdint.h>
+#include <iostream>
+#include <sstream>
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+static uint8_t MostSignificantDigit (uint64_t value)
+{
+  uint8_t n = 0;
+  do
+    {
+      n++;
+      value /= 10;
+    } while (value != 0);
+  return n;
+}
+
+static uint64_t PowerOfTen (uint8_t n)
+{
+  uint64_t retval = 1;
+  while (n > 0)
+    {
+      retval *= 10;
+      n--;
+    }
+  return retval;
+}
+
+std::ostream &operator << (std::ostream &os, const uint64x64_t &value)
+{
+  int64_t hi = value.GetHigh ();
+  os << ((hi<0)?"-":"+") << ((hi<0)?-hi:hi) << ".";
+  uint64_t low = value.GetLow ();
+  uint8_t msd = MostSignificantDigit (~((uint64_t)0));
+  do
+    {
+      msd--;
+      uint64_t pow = PowerOfTen (msd);
+      uint8_t digit = low / pow;
+      NS_ASSERT (digit < 10);
+      os << (uint16_t) digit;
+      low -= digit * pow;
+    } while (msd > 0 && low > 0);
+  return os;
+}
+
+static uint64_t ReadDigits (std::string str)
+{
+  const char *buf = str.c_str ();
+  uint64_t retval = 0;
+  while (*buf != 0)
+    {
+      retval *= 10;
+      retval += *buf - 0x30;
+      buf++;
+    }
+  return retval;
+}
+
+std::istream &operator >> (std::istream &is, uint64x64_t &value)
+{
+  std::string str;
+
+  is >> str;
+  bool negative;
+  // skip heading spaces
+  std::string::size_type cur;
+  cur = str.find_first_not_of (" ");
+  std::string::size_type next;
+  // first, remove the sign.
+  next = str.find ("-", cur);
+  if (next != std::string::npos)
+    {
+      negative = true;
+      next++;
+    }
+  else
+    {
+      next = str.find ("+", cur);
+      if (next != std::string::npos)
+	{
+	  next++;
+	}
+      else
+	{
+	  next = cur;
+	}
+      negative = false;
+    }
+  cur = next;
+  int64_t hi;
+  uint64_t lo;
+  next = str.find(".", cur);
+  if (next != std::string::npos)
+    {
+      hi = ReadDigits (str.substr (cur, next-cur));
+      lo = ReadDigits (str.substr (next+1, str.size()-(next+1)));
+    }
+  else
+    {
+      hi = ReadDigits (str.substr (cur, str.size ()-cur));
+      lo = 0;
+    }
+  hi = negative?-hi:hi;
+  value = uint64x64_t (hi, lo);
+  return is;
+}
+
+} // namespace ns3
+
+#include "ns3/test.h"
+
+namespace ns3
+{
+
+class Uint64x64FracTestCase : public TestCase
+{
+public:
+  Uint64x64FracTestCase ();
+  virtual bool DoRun (void);
+  void CheckFrac (int64_t hi, uint64_t lo);
+};
+
+void 
+Uint64x64FracTestCase::CheckFrac (int64_t hi, uint64_t lo)
+{
+  uint64x64_t tmp = uint64x64_t (hi,lo);
+  NS_TEST_EXPECT_MSG_EQ (tmp.GetHigh (), hi,
+			 "High part does not match");
+  NS_TEST_EXPECT_MSG_EQ (tmp.GetLow (), lo,
+			 "Low part does not match");
+}
+
+Uint64x64FracTestCase::Uint64x64FracTestCase ()
+  : TestCase ("Check that we can manipulate the high and low part of every number")
+{
+}
+bool
+Uint64x64FracTestCase::DoRun (void)
+{
+  CheckFrac (1, 0);
+  CheckFrac (1, 1);
+  CheckFrac (-1, 0);
+  CheckFrac (-1, 1);
+  return GetErrorStatus ();
+}
+
+
+class Uint64x64InputTestCase : public TestCase
+{
+public:
+  Uint64x64InputTestCase ();
+  virtual bool DoRun (void);
+  void CheckString (std::string str, int64_t hi, uint64_t lo);
+};
+Uint64x64InputTestCase::Uint64x64InputTestCase ()
+  : TestCase ("Check that we parse Uint64x64 numbers as strings")
+{
+}
+void 
+Uint64x64InputTestCase::CheckString (std::string str, int64_t hi, uint64_t lo)
+{
+  std::istringstream iss;
+  iss.str (str);
+  uint64x64_t hp;
+  iss >> hp;
+  NS_TEST_EXPECT_MSG_EQ (hp.GetHigh (), hi, "High parts do not match for input string " << str);
+  NS_TEST_EXPECT_MSG_EQ (hp.GetLow (), lo, "Low parts do not match for input string " << str);
+}
+bool
+Uint64x64InputTestCase::DoRun (void)
+{
+  CheckString ("1", 1, 0);
+  CheckString ("+1", 1, 0);
+  CheckString ("-1", -1, 0);
+  CheckString ("1.0", 1, 0);
+  CheckString ("+1.0", 1, 0);
+  CheckString ("001.0", 1, 0);
+  CheckString ("+001.0", 1, 0);
+  CheckString ("020.0", 20, 0);
+  CheckString ("+020.0", 20, 0);
+  CheckString ("-1.0", -1, 0);
+  CheckString ("-1.0000", -1, 0);
+  CheckString ("1.0000000", 1, 0);
+  CheckString ("1.08446744073709551615", 1, 8446744073709551615LL);
+  CheckString ("-1.08446744073709551615", -1, 8446744073709551615LL);
+  
+  return GetErrorStatus ();
+}
+
+class Uint64x64InputOutputTestCase : public TestCase
+{
+public:
+  Uint64x64InputOutputTestCase ();
+  virtual bool DoRun (void);
+  void CheckString (std::string str);
+};
+Uint64x64InputOutputTestCase::Uint64x64InputOutputTestCase ()
+  : TestCase ("Check that we can roundtrip Uint64x64 numbers as strings")
+{
+}
+void 
+Uint64x64InputOutputTestCase::CheckString (std::string str)
+{
+  std::istringstream iss;
+  iss.str (str);
+  uint64x64_t value;
+  iss >> value;
+  std::ostringstream oss;
+  oss << value;
+  NS_TEST_EXPECT_MSG_EQ (oss.str (), str, "Converted string does not match expected string");
+}
+bool
+Uint64x64InputOutputTestCase::DoRun (void)
+{
+  CheckString ("+1.0");
+  CheckString ("-1.0");
+  CheckString ("+20.0");
+  CheckString ("+1.08446744073709551615");
+  CheckString ("-1.08446744073709551615");
+  CheckString ("+1.18446744073709551615");
+  CheckString ("-1.18446744073709551615");
+  
+  return GetErrorStatus ();
+}
+
+#define CHECK_EXPECTED(a,b) \
+  NS_TEST_ASSERT_MSG_EQ ((a).GetHigh (),b,"Arithmetic failure: " << ((a).GetHigh ()) << "!=" << (b))
+
+#define V(v) \
+  uint64x64_t (v)
+
+class Uint64x64ArithmeticTestCase : public TestCase
+{
+public:
+  Uint64x64ArithmeticTestCase ();
+  virtual bool DoRun (void);
+};
+
+Uint64x64ArithmeticTestCase::Uint64x64ArithmeticTestCase ()
+  : TestCase ("Check basic arithmetic operations")
+{
+}
+bool
+Uint64x64ArithmeticTestCase::DoRun (void)
+{
+  uint64x64_t a, b;
+
+  CHECK_EXPECTED (V(1) - V(1), 0);
+  CHECK_EXPECTED (V(1) - V(2), -1);
+  CHECK_EXPECTED (V(1) - V(3), -2);
+  CHECK_EXPECTED (V(1) - V(-1), 2);
+  CHECK_EXPECTED (V(1) - V(-2), 3);
+  CHECK_EXPECTED (V(-3) - V(-4), 1);
+  CHECK_EXPECTED (V(-2) - V(3), -5);
+  CHECK_EXPECTED (V(1) + V(2), 3);
+  CHECK_EXPECTED (V(1) + V(-3), -2);
+  CHECK_EXPECTED (V(0) + V(0), 0);
+  CHECK_EXPECTED (V(0) * V(0), 0);
+  CHECK_EXPECTED (V(0) * V(1), 0);
+  CHECK_EXPECTED (V(0) * V(-1), 0);
+  CHECK_EXPECTED (V(1) * V(0), 0);
+  CHECK_EXPECTED (V(1) * V(1), 1);
+  CHECK_EXPECTED (V(1) * V(-1), -1);
+  CHECK_EXPECTED (V(-1) * V(-1), 1);
+  CHECK_EXPECTED (V(0) * V(1), 0);
+  CHECK_EXPECTED (V(0) * V(-1), 0);
+  CHECK_EXPECTED (V(-1) * V(1), -1);
+
+
+  CHECK_EXPECTED (V (2) * V(3) / V(3), 2);
+
+  // Below, the division loses precision because 2/3 is not
+  // representable exactly in 64.64 integers. So, we got
+  // something super close but the final rounding kills us.
+  CHECK_EXPECTED (V(2) / V(3) * V(3), 1);
+
+  // The example below shows that we really do not lose
+  // much precision internally: it is almost always the
+  // final conversion which loses precision.
+  CHECK_EXPECTED (V (2000000000) / V(3) * V(3), 1999999999);
+
+  return GetErrorStatus ();
+}
+
+class Uint64x64Bug455TestCase : public TestCase
+{
+public:
+  Uint64x64Bug455TestCase ();
+  virtual bool DoRun (void);
+};
+
+Uint64x64Bug455TestCase::Uint64x64Bug455TestCase ()
+  : TestCase ("Test case for bug 455")
+{
+}
+bool
+Uint64x64Bug455TestCase::DoRun (void)
+{
+  uint64x64_t a = uint64x64_t (0.1);
+  a /= uint64x64_t (1.25);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 0.08, "The original testcase");
+  a = uint64x64_t (0.5);
+  a *= uint64x64_t (5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 2.5, "Simple test for multiplication");
+  a = uint64x64_t (-0.5);
+  a *= uint64x64_t (5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -2.5, "Test sign, first operation negative");
+  a = uint64x64_t (-0.5);
+  a *=uint64x64_t (-5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 2.5, "both operands negative");
+  a = uint64x64_t (0.5);
+  a *= uint64x64_t (-5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -2.5, "only second operand negative");
+
+  return GetErrorStatus ();
+}
+
+class Uint64x64Bug863TestCase : public TestCase
+{
+public:
+  Uint64x64Bug863TestCase ();
+  virtual bool DoRun (void);
+};
+
+Uint64x64Bug863TestCase::Uint64x64Bug863TestCase ()
+  : TestCase ("Test case for bug 863")
+{
+}
+bool
+Uint64x64Bug863TestCase::DoRun (void)
+{
+  uint64x64_t a = uint64x64_t (0.9);
+  a /= uint64x64_t (1);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 0.9, "The original testcase");
+  a = uint64x64_t (0.5);
+  a /= uint64x64_t (0.5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 1.0, "Simple test for division");
+  a = uint64x64_t (-0.5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -0.5, "Check that we actually convert doubles correctly");
+  a /= uint64x64_t (0.5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -1.0, "first argument negative");
+  a = uint64x64_t (0.5);
+  a /= uint64x64_t (-0.5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), -1.0, "second argument negative");
+  a = uint64x64_t (-0.5);
+  a /= uint64x64_t (-0.5);
+  NS_TEST_ASSERT_MSG_EQ (a.GetDouble (), 1.0, "both arguments negative");
+
+  return GetErrorStatus ();
+}
+
+class Uint64x64CompareTestCase : public TestCase
+{
+public:
+  Uint64x64CompareTestCase ();
+  virtual bool DoRun (void);
+};
+Uint64x64CompareTestCase::Uint64x64CompareTestCase ()
+  : TestCase ("Check basic compare operations")
+{
+}
+bool
+Uint64x64CompareTestCase::DoRun (void)
+{
+
+  NS_TEST_ASSERT_MSG_EQ ((V(-1) < V(1)), true, "a is smaller than b");
+  NS_TEST_ASSERT_MSG_EQ ((V(-1) > V(-2)), true, "a is bigger than b");
+  NS_TEST_ASSERT_MSG_EQ ((V(-1) == V(-1)), true, "a is equal to b");
+
+  NS_TEST_ASSERT_MSG_EQ ((V(1) > V(-1)), true, "a is bigger than b");
+  NS_TEST_ASSERT_MSG_EQ ((V(1) < V(2)), true, "a is smaller than b");
+
+  return GetErrorStatus ();
+}
+
+class Uint64x64InvertTestCase : public TestCase
+{
+public:
+  Uint64x64InvertTestCase ();
+  virtual bool DoRun (void);
+};
+
+Uint64x64InvertTestCase::Uint64x64InvertTestCase ()
+  : TestCase ("Test case for invertion")
+{
+}
+
+bool
+Uint64x64InvertTestCase::DoRun (void)
+{
+#define TEST(factor)                                                    \
+  do {                                                                  \
+    uint64x64_t a;							\
+    a = uint64x64_t::Invert (factor);					\
+    uint64x64_t b = V (factor);						\
+    b.MulByInvert (a);                                                  \
+    NS_TEST_ASSERT_MSG_EQ (b.GetHigh (), 1,				\
+			   "x * 1/x should be 1 for x=" << factor);     \
+    uint64x64_t c = V (1);						\
+    c.MulByInvert (a);                                                  \
+    NS_TEST_ASSERT_MSG_EQ (c.GetHigh (), 0,				\
+			   "1 * 1/x should be 0 for x=" << factor);     \
+    uint64x64_t d = V (1);						\
+    d /= (V(factor));                                                  \
+    NS_TEST_ASSERT_MSG_EQ (d.GetDouble (), c.GetDouble (),              \
+			   "1 * 1/x should be equal to 1/x for x=" << factor); \
+    uint64x64_t e = V (-factor);					\
+    e.MulByInvert (a);                                                  \
+    NS_TEST_ASSERT_MSG_EQ (e.GetHigh (), -1,				\
+			   "-x * 1/x should be -1 for x=" << factor);   \
+  } while(false)
+  TEST(2);
+  TEST(3);
+  TEST(4);
+  TEST(5);
+  TEST(6);
+  TEST(10);
+  TEST(99);
+  TEST(100);
+  TEST(1000);
+  TEST(10000);
+  TEST(100000);
+  TEST(100000);
+  TEST(1000000);
+  TEST(10000000);
+  TEST(100000000);
+  TEST(1000000000);
+  TEST(10000000000LL);
+  TEST(100000000000LL);
+  TEST(1000000000000LL);
+  TEST(10000000000000LL);
+  TEST(100000000000000LL);
+  TEST(1000000000000000LL);
+#undef TEST
+  return GetErrorStatus ();
+}
+
+
+
+static class Uint64x64128TestSuite : public TestSuite
+{
+public:
+  Uint64x64128TestSuite ()
+    : TestSuite ("uint64x64", UNIT)
+  {
+    AddTestCase (new Uint64x64FracTestCase ());
+    AddTestCase (new Uint64x64InputTestCase ());
+    AddTestCase (new Uint64x64InputOutputTestCase ());
+    AddTestCase (new Uint64x64ArithmeticTestCase ());
+    AddTestCase (new Uint64x64Bug455TestCase ());
+    AddTestCase (new Uint64x64Bug863TestCase ());
+    AddTestCase (new Uint64x64CompareTestCase ());
+    AddTestCase (new Uint64x64InvertTestCase ());
+  }
+} g_uint64x64TestSuite;
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/simulator/uint64x64.h	Tue Aug 24 16:36:41 2010 +0200
@@ -0,0 +1,51 @@
+#ifndef UINT64X64_H
+#define UINT64X64_H
+
+#include "ns3/simulator-config.h"
+
+#if defined (UINT64x64_USE_DOUBLE)
+#include "uint64x64-double.h"
+#elif defined (UINT64x64_USE_CAIRO)
+#include "uint64x64-cairo.h"
+#elif defined (UINT64x64_USE_128)
+#include "uint64x64-128.h"
+#endif
+
+#include <iostream>
+
+namespace ns3 {
+
+inline uint64x64_t operator + (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  uint64x64_t tmp = lhs;
+  tmp += rhs;
+  return tmp;
+}
+
+inline uint64x64_t operator - (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  uint64x64_t tmp = lhs;
+  tmp -= rhs;
+  return tmp;
+}
+
+inline uint64x64_t operator * (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  uint64x64_t tmp = lhs;
+  tmp *= rhs;
+  return tmp;
+}
+
+inline uint64x64_t operator / (const uint64x64_t &lhs, const uint64x64_t &rhs)
+{
+  uint64x64_t tmp = lhs;
+  tmp /= rhs;
+  return tmp;
+}
+
+std::ostream &operator << (std::ostream &os, const uint64x64_t &val);
+std::istream &operator << (std::istream &is, uint64x64_t &val);
+
+} // namespace ns3
+
+#endif /* UINT64X64_H */
--- a/src/simulator/wscript	Mon Aug 23 19:01:11 2010 -0700
+++ b/src/simulator/wscript	Tue Aug 24 16:36:41 2010 +0200
@@ -20,15 +20,15 @@
 
 
     if Options.options.high_precision_as_double:
-        conf.define('USE_HIGH_PRECISION_DOUBLE', 1)
+        conf.define('UINT64x64_USE_DOUBLE', 1)
         conf.env['USE_HIGH_PRECISION_DOUBLE'] = 1
         highprec = 'long double'
     elif a or b:
-        conf.define('USE_HIGH_PRECISION_128', 1)
+        conf.define('UINT64x64_USE_128', 1)
         conf.env['USE_HIGH_PRECISION_128'] = 1
         highprec = '128-bit integer'
     else:
-        conf.define('USE_HIGH_PRECISION_CAIRO', 1)
+        conf.define('UINT64x64_USE_CAIRO', 1)
         conf.env['USE_HIGH_PRECISION_CAIRO'] = 1
         highprec = 'cairo 128-bit integer'
 
@@ -54,8 +54,7 @@
 def build(bld):
     sim = bld.create_ns3_module('simulator', ['core'])
     sim.source = [
-        'high-precision.cc',
-        'time-base.cc',
+        'uint64x64.cc',
         'time.cc',
         'event-id.cc',
         'scheduler.cc',
@@ -77,8 +76,7 @@
     headers = bld.new_task_gen('ns3header')
     headers.module = 'simulator'
     headers.source = [
-        'high-precision.h',
-        'time-base.h',
+        'uint64x64.h',
         'nstime.h',
         'event-id.h',
         'event-impl.h',
@@ -101,17 +99,16 @@
 
     env = bld.env_of_name('default')
     if env['USE_HIGH_PRECISION_DOUBLE']:
-        headers.source.extend(['high-precision-double.h'])
+        headers.source.extend(['uint64x64-double.h'])
     elif env['USE_HIGH_PRECISION_128']:
-        headers.source.extend(['high-precision-128.h'])
-        sim.source.extend(['high-precision-128.cc'])
+        headers.source.extend(['uint64x64-128.h'])
+        sim.source.extend(['uint64x64-128.cc'])
     elif env['USE_HIGH_PRECISION_CAIRO']:
         sim.source.extend([
-            'high-precision-cairo.cc',
-#            'cairo-wideint.c',
+            'uint64x64-cairo.cc',
             ])
         headers.source.extend([
-            'high-precision-cairo.h',
+            'uint64x64-cairo.h',
             'cairo-wideint-private.h',
             ])