A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
int64x64-cairo.h
Go to the documentation of this file.
1 #include "ns3/core-config.h"
2 #if !defined(INT64X64_CAIRO_H) && defined (INT64X64_USE_CAIRO) && !defined(PYTHON_SCAN)
3 #define INT64X64_CAIRO_H
4 
5 #include <cmath> // pow
6 
8 
9 
10 namespace ns3 {
11 
16 class int64x64_t
17 {
19  static const uint64_t HPCAIRO_MASK_HI_BIT = (((uint64_t)1)<<63);
21  static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
34 #define HP_MAX_64 (std::pow (2.0L, 64))
35 
36 public:
44  enum impl_type {
45  int128_impl,
46  cairo_impl,
47  ld_impl,
48  };
49 
51  static const enum impl_type implementation = cairo_impl;
52 
54  inline int64x64_t ()
55  {
56  _v.hi = 0;
57  _v.lo = 0;
58  }
65  inline int64x64_t (const double value)
66  {
67  const int64x64_t tmp ((long double)value);
68  _v = tmp._v;
69  }
70  inline int64x64_t (const long double value)
71  {
72  const bool negative = value < 0;
73  const long double v = negative ? -value : value;
74 
75  long double fhi;
76  long double flo = std::modf (v, &fhi);
77  // Add 0.5 to round, which improves the last count
78  // This breaks these tests:
79  // TestSuite devices-mesh-dot11s-regression
80  // TestSuite devices-mesh-flame-regression
81  // TestSuite routing-aodv-regression
82  // TestSuite routing-olsr-regression
83  // Setting round = 0; breaks:
84  // TestSuite int64x64
85  const long double round = 0.5;
86  flo = flo * HP_MAX_64 + round;
87  cairo_int64_t hi = fhi;
88  const cairo_uint64_t lo = flo;
89  if (flo >= HP_MAX_64)
90  {
91  // conversion to uint64 rolled over
92  ++hi;
93  }
94  _v.hi = hi;
95  _v.lo = lo;
96  _v = negative ? _cairo_int128_negate (_v) : _v;
97  }
106  inline int64x64_t (const int v)
107  {
108  _v.hi = v;
109  _v.lo = 0;
110  }
111  inline int64x64_t (const long int v)
112  {
113  _v.hi = v;
114  _v.lo = 0;
115  }
116  inline int64x64_t (const long long int v)
117  {
118  _v.hi = v;
119  _v.lo = 0;
120  }
121  inline int64x64_t (const unsigned int v)
122  {
123  _v.hi = v;
124  _v.lo = 0;
125  }
126  inline int64x64_t (const unsigned long int v)
127  {
128  _v.hi = v;
129  _v.lo = 0;
130  }
131  inline int64x64_t (const unsigned long long int v)
132  {
133  _v.hi = v;
134  _v.lo = 0;
135  }
143  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
144  {
145  _v.hi = hi;
146  _v.lo = lo;
147  }
148 
154  inline int64x64_t (const int64x64_t & o)
155  : _v (o._v) {}
161  inline int64x64_t & operator = (const int64x64_t & o)
162  {
163  _v = o._v;
164  return *this;
165  }
166 
172  inline double GetDouble (void) const
173  {
174  const bool negative = _cairo_int128_negative (_v);
175  const cairo_int128_t value = negative ? _cairo_int128_negate (_v) : _v;
176  const long double fhi = value.hi;
177  const long double flo = value.lo / HP_MAX_64;
178  long double retval = fhi;
179  retval += flo;
180  retval = negative ? -retval : retval;
181  return retval;
182  }
188  inline int64_t GetHigh (void) const
189  {
190  return (int64_t)_v.hi;
191  }
197  inline uint64_t GetLow (void) const
198  {
199  return _v.lo;
200  }
201 
210  void MulByInvert (const int64x64_t & o);
211 
225  static int64x64_t Invert (const uint64_t v);
226 
227 private:
228  friend bool operator == (const int64x64_t & lhs, const int64x64_t & rhs);
229 
230  friend bool operator < (const int64x64_t & lhs, const int64x64_t & rhs);
231  friend bool operator > (const int64x64_t & lhs, const int64x64_t & rhs);
232 
233  friend int64x64_t & operator += ( int64x64_t & lhs, const int64x64_t & rhs);
234  friend int64x64_t & operator -= ( int64x64_t & lhs, const int64x64_t & rhs);
235  friend int64x64_t & operator *= ( int64x64_t & lhs, const int64x64_t & rhs);
236  friend int64x64_t & operator /= ( int64x64_t & lhs, const int64x64_t & rhs);
237 
238  friend int64x64_t operator - (const int64x64_t & lhs);
239  friend int64x64_t operator ! (const int64x64_t & lhs);
240 
246  void Mul (const int64x64_t & o);
252  void Div (const int64x64_t & o);
277  static cairo_uint128_t Umul (const cairo_uint128_t a, const cairo_uint128_t b);
285  static cairo_uint128_t Udiv (const cairo_uint128_t a, const cairo_uint128_t b);
295  static cairo_uint128_t UmulByInvert (const cairo_uint128_t a, const cairo_uint128_t b);
296 
298 
299 }; // class int64x64_t
300 
301 
306 inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
307 {
308  return _cairo_int128_eq (lhs._v, rhs._v);
309 }
314 inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
315 {
316  return _cairo_int128_lt (lhs._v, rhs._v);
317 }
322 inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
323 {
324  return _cairo_int128_gt (lhs._v, rhs._v);
325 }
326 
331 inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
332 {
333  lhs._v = _cairo_int128_add( lhs._v, rhs._v );
334  return lhs;
335 }
340 inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
341 {
342  lhs._v = _cairo_int128_sub( lhs._v, rhs._v );
343  return lhs;
344 }
349 inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
350 {
351  lhs.Mul (rhs);
352  return lhs;
353 }
358 inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
359 {
360  lhs.Div (rhs);
361  return lhs;
362 }
363 
368 inline int64x64_t operator + (const int64x64_t & lhs)
369 {
370  return lhs;
371 }
376 inline int64x64_t operator - (const int64x64_t & lhs)
377 {
378  int64x64_t tmp = lhs;
379  tmp._v = _cairo_int128_negate (tmp._v);
380  return tmp;
381 }
386 inline int64x64_t operator ! (const int64x64_t & lhs)
387 {
388  return (lhs == int64x64_t ()) ? int64x64_t (1, 0) : int64x64_t ();
389 }
390 
391 
392 } // namespace ns3
393 
394 #endif /* INT64X64_CAIRO_H */
long double implementation
Definition: int64x64-128.h:53
uint64_t GetLow(void) const
Get the fractional portion of this value, unscaled.
Definition: int64x64-128.h:201
int64x64_t operator+(const int64x64_t &lhs)
Unary plus operator.
Definition: int64x64-128.h:381
int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Compound division operator.
Definition: int64x64-128.h:371
static uint128_t Udiv(const uint128_t a, const uint128_t b)
Unsigned division of Q64.64 values.
Definition: int64x64-128.cc:87
static int64x64_t Invert(const uint64_t v)
Compute the inverse of an integer value.
int64x64_t operator-(const int64x64_t &lhs)
Unary negation operator (change sign operator)
Definition: int64x64-128.h:389
impl_type
Type tag for the underlying implementation.
Definition: int64x64-128.h:50
int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:344
int64_t cairo_int64_t
static enum impl_type implementation
Type tag for this implementation.
Definition: int64x64-128.h:57
void MulByInvert(const int64x64_t &o)
Multiply this value by a Q0.128 value, presumably representing an inverse, completing a division oper...
static uint128_t UmulByInvert(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 and Q0.128 values.
double GetDouble(void) const
Get this value as a double.
Definition: int64x64-128.h:175
friend int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:397
friend int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Compound multiplication operator.
Definition: int64x64-128.h:362
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Equality operator.
Definition: int64x64-128.h:319
int I _cairo_int128_lt(cairo_int128_t a, cairo_int128_t b)
friend int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Compound division operator.
Definition: int64x64-128.h:371
static uint128_t Umul(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 values.
Definition: int64x64-128.cc:38
int128_t _v
The Q64.64 value.
Definition: int64x64-128.h:310
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:353
#define _cairo_int128_eq(a, b)
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:29
int64x64_t()
Default constructor.
Definition: int64x64-128.h:60
bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Less than operator.
Definition: int64x64-128.h:327
#define _cairo_int128_sub(a, b)
int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Compound multiplication operator.
Definition: int64x64-128.h:362
#define _cairo_int128_negative(a)
uint64_t cairo_uint64_t
#define _cairo_int128_gt(a, b)
Native int128_t implementation.
Definition: int64x64-128.h:51
static const uint64_t HP_MASK_LO
Mask for fraction part.
Definition: int64x64-128.h:25
int64x64_t & operator=(const int64x64_t &o)
Assignment.
Definition: int64x64-128.h:164
#define HP_MAX_64
Floating point value of HP_MASK_LO + 1 We really want:
Definition: int64x64-128.h:40
void Div(const int64x64_t &o)
Implement /=.
Definition: int64x64-128.cc:78
friend bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Less than operator.
Definition: int64x64-128.h:327
bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Greater operator.
Definition: int64x64-128.h:335
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:89
#define _cairo_int128_negate(a)
int64_t GetHigh(void) const
Get the integer portion.
Definition: int64x64-128.h:191
cairo wideint implementation
Definition: int64x64-128.h:52
friend int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:344
#define _cairo_int128_add(a, b)
friend int64x64_t operator-(const int64x64_t &lhs)
Unary negation operator (change sign operator)
Definition: int64x64-128.h:389
friend bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Greater operator.
Definition: int64x64-128.h:335
int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:397
int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:353