--- a/SConstruct Mon Dec 04 10:17:53 2006 +0100
+++ b/SConstruct Mon Dec 04 10:33:02 2006 +0100
@@ -49,7 +49,6 @@
simu.add_dep('core')
simu.add_sources([
'high-precision.cc',
- 'cairo-wideint.c',
'time.cc',
'event-id.cc',
'scheduler.cc',
@@ -61,7 +60,6 @@
'simulator.cc',
])
simu.add_headers([
- 'cairo-wideint-private.h',
'scheduler-heap.h',
'scheduler-map.h',
'scheduler-list.h'
@@ -76,12 +74,16 @@
'scheduler-factory.h',
])
high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
-if high_precision_as_double == 1:
+if high_precision_as_double == 'y':
simu.add_inst_header ('high-precision-double.h')
simu.add_source ('high-precision-double.cc')
else:
simu.add_inst_header ('high-precision-128.h')
- simu.add_source ('high-precision-128.cc')
+ simu.add_header ('cairo-wideint-private.h')
+ simu.add_sources ([
+ 'high-precision-128.cc',
+ 'cairo-wideint.c',
+ ])
def config_simulator (env, config):
retval = []
--- a/src/simulator/high-precision-128.cc Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/high-precision-128.cc Mon Dec 04 10:33:02 2006 +0100
@@ -19,64 +19,93 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "high-precision-128.h"
+#include <math.h>
namespace ns3 {
-HighPrecision::HighPrecision ()
- : m_high (0),
- m_low (0)
-{}
+const double HighPrecision::MAX_64 = 18446744073709551615.0;
-HighPrecision::HighPrecision (int64_t high, int64_t low)
- : m_high (high),
- m_low (low)
-{}
+HighPrecision::HighPrecision ()
+{
+ m_value = _cairo_int32_to_int128 (0);
+ m_value = _cairo_int128_lsl (m_value, 64);
+}
+
+HighPrecision::HighPrecision (int64_t value, bool dummy)
+{
+ m_value = _cairo_int64_to_int128 (value);
+ m_value = _cairo_int128_lsl (m_value, 64);
+}
HighPrecision::HighPrecision (double value)
- : m_high (0), // XXX
- m_low (0) // XXX
-{}
+{
+ int64_t hi = (int64_t) floor (value);
+ uint64_t lo = (uint64_t) ((value - floor (value)) * MAX_64);
+ m_value = _cairo_int64_to_int128 (hi);
+ m_value = _cairo_int128_lsl (m_value, 64);
+ cairo_int128_t clo = _cairo_uint128_to_int128 (_cairo_uint64_to_uint128 (lo));
+ m_value = _cairo_int128_add (m_value, clo);
+}
int64_t
-HighPrecision::GetHigh (void) const
+HighPrecision::GetInteger (void) const
{
- return m_high;
-}
-int64_t
-HighPrecision::GetLow (void) const
-{
- return m_low;
+ cairo_int128_t value = _cairo_int128_rsa (m_value, 64);
+ return _cairo_int128_to_int64 (value);
}
double
HighPrecision::GetDouble (void) const
{
- return 0.0;
+ cairo_int128_t value = _cairo_int128_rsa (m_value, 64);
+ cairo_int128_t rem = _cairo_int128_sub (m_value, value);
+ double frem = _cairo_int128_to_int64 (rem);
+ frem /= MAX_64;
+ double retval = _cairo_int128_to_int64 (value);
+ retval += frem;
+ return retval;
}
bool
HighPrecision::Add (HighPrecision const &o)
{
+ m_value = _cairo_int128_add (m_value, o.m_value);
return false;
}
bool
HighPrecision::Sub (HighPrecision const &o)
{
+ m_value = _cairo_int128_sub (m_value, o.m_value);
return false;
}
bool
HighPrecision::Mul (HighPrecision const &o)
{
+ m_value = _cairo_int128_mul (m_value, o.m_value);
return false;
}
bool
HighPrecision::Div (HighPrecision const &o)
{
+ cairo_quorem128_t qr;
+ qr = _cairo_int128_divrem (m_value, o.m_value);
+ m_value = qr.quo;
return false;
}
int
HighPrecision::Compare (HighPrecision const &o) const
{
- return 0;
+ if (_cairo_int128_lt (m_value, o.m_value))
+ {
+ return -1;
+ }
+ else if (_cairo_int128_eq (m_value, o.m_value))
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
}
HighPrecision
HighPrecision::Zero (void)
--- a/src/simulator/high-precision-128.h Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/high-precision-128.h Mon Dec 04 10:33:02 2006 +0100
@@ -22,6 +22,7 @@
#define HIGH_PRECISION_128_H
#include <stdint.h>
+#include "cairo-wideint-private.h"
namespace ns3 {
@@ -34,11 +35,10 @@
{
public:
HighPrecision ();
- HighPrecision (int64_t high, int64_t low);
+ HighPrecision (int64_t value, bool dummy);
HighPrecision (double value);
- int64_t GetHigh (void) const;
- int64_t GetLow (void) const;
+ int64_t GetInteger (void) const;
double GetDouble (void) const;
bool Add (HighPrecision const &o);
bool Sub (HighPrecision const &o);
@@ -48,8 +48,8 @@
int Compare (HighPrecision const &o) const;
static HighPrecision Zero (void);
private:
- int64_t m_high;
- int64_t m_low;
+ static const double MAX_64;
+ cairo_int128_t m_value;
};
}; // namespace ns3
--- a/src/simulator/high-precision-double.cc Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/high-precision-double.cc Mon Dec 04 10:33:02 2006 +0100
@@ -26,14 +26,12 @@
namespace ns3 {
-const double HighPrecision::MAX_64 = 18446744073709551615.0;
-
HighPrecision::HighPrecision ()
: m_value (0.0)
{}
-HighPrecision::HighPrecision (int64_t high, int64_t low)
- : m_value (((double)high) + (((double)low)/MAX_64))
+HighPrecision::HighPrecision (int64_t value, bool dummy)
+ : m_value ((double)value)
{}
HighPrecision::HighPrecision (double value)
@@ -41,15 +39,10 @@
{}
int64_t
-HighPrecision::GetHigh (void) const
+HighPrecision::GetInteger (void) const
{
return (int64_t)floor (m_value);
}
-int64_t
-HighPrecision::GetLow (void) const
-{
- return (int64_t)((m_value - floor (m_value)) * MAX_64);
-}
double
HighPrecision::GetDouble (void) const
--- a/src/simulator/high-precision-double.h Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/high-precision-double.h Mon Dec 04 10:33:02 2006 +0100
@@ -36,11 +36,10 @@
{
public:
HighPrecision ();
- HighPrecision (int64_t high, int64_t low);
+ HighPrecision (int64_t value, bool dummy);
HighPrecision (double value);
- int64_t GetHigh (void) const;
- int64_t GetLow (void) const;
+ int64_t GetInteger (void) const;
double GetDouble (void) const;
bool Add (HighPrecision const &o);
bool Sub (HighPrecision const &o);
--- a/src/simulator/high-precision.cc Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/high-precision.cc Mon Dec 04 10:33:02 2006 +0100
@@ -30,7 +30,9 @@
{
if (value.Compare (HighPrecision::Zero ()) <= 0)
{
- return HighPrecision::Zero ().Sub (value);
+ HighPrecision v = HighPrecision::Zero ();
+ v.Sub (value);
+ return v;
}
else
{
--- a/src/simulator/nstime.h Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/nstime.h Mon Dec 04 10:33:02 2006 +0100
@@ -82,12 +82,6 @@
TimeUnit (HighPrecision data);
/**
- * \return the ns3::HighPrecision object which holds the value
- * stored in this Time<N> type.
- */
- HighPrecision GetHighPrecision (void) const;
-
- /**
* \return true if the time is zero, false otherwise.
*/
bool IsZero (void) const;
@@ -108,6 +102,15 @@
*/
bool IsStrictlyPositive (void) const;
+ /**
+ * 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 Time<N> type.
+ */
+ HighPrecision GetHighPrecision (void) const;
+
private:
HighPrecision m_data;
};
--- a/src/simulator/time.cc Mon Dec 04 10:17:53 2006 +0100
+++ b/src/simulator/time.cc Mon Dec 04 10:33:02 2006 +0100
@@ -34,27 +34,27 @@
Time::GetSeconds (void) const
{
HighPrecision seconds = GetHighPrecision ();
- seconds.Div (HighPrecision (1000000000, 0));
+ seconds.Div (HighPrecision (1000000000, false));
return seconds.GetDouble ();
}
int32_t
Time::GetMilliSeconds (void) const
{
HighPrecision ms = GetHighPrecision ();
- ms.Div (HighPrecision (1000000, 0));
- return (int32_t) ms.GetHigh ();
+ ms.Div (HighPrecision (1000000, false));
+ return (int32_t) ms.GetInteger ();
}
int64_t
Time::GetMicroSeconds (void) const
{
HighPrecision us = GetHighPrecision ();
- us.Div (HighPrecision (1000, 0));
- return us.GetHigh ();
+ us.Div (HighPrecision (1000, false));
+ return us.GetInteger ();
}
int64_t
Time::GetNanoSeconds (void) const
{
- return GetHighPrecision ().GetHigh ();
+ return GetHighPrecision ().GetInteger ();
}
@@ -68,19 +68,19 @@
: TimeUnit<1> ()
{}
MilliSeconds::MilliSeconds (uint32_t ms)
- : TimeUnit<1> (HighPrecision (ms * 1000000, 0))
+ : TimeUnit<1> (HighPrecision (ms * 1000000, false))
{}
MicroSeconds::MicroSeconds ()
: TimeUnit<1> ()
{}
MicroSeconds::MicroSeconds (uint32_t us)
- : TimeUnit<1> (HighPrecision (us * 1000, 0))
+ : TimeUnit<1> (HighPrecision (us * 1000, false))
{}
NanoSeconds::NanoSeconds ()
: TimeUnit<1> ()
{}
NanoSeconds::NanoSeconds (uint32_t ns)
- : TimeUnit<1> (HighPrecision (ns, 0))
+ : TimeUnit<1> (HighPrecision (ns, false))
{}
Now::Now ()