A Discrete-Event Network Simulator
API
int64x64-cairo.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  */
19 
20 #include "ns3/core-config.h"
21 #if !defined(INT64X64_CAIRO_H) && defined (INT64X64_USE_CAIRO) && !defined(PYTHON_SCAN)
22 #define INT64X64_CAIRO_H
23 
24 #include <cmath> // pow
25 
26 #include "cairo-wideint-private.h"
27 
34 namespace ns3 {
35 
40 class int64x64_t
41 {
43  static const uint64_t HPCAIRO_MASK_HI_BIT = (((uint64_t)1) << 63);
45  static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
58 #define HP_MAX_64 (std::pow (2.0L, 64))
59 
60 public:
68  enum impl_type
69  {
70  int128_impl,
71  cairo_impl,
72  ld_impl,
73  };
74 
76  static const enum impl_type implementation = cairo_impl;
77 
79  inline int64x64_t ()
80  {
81  _v.hi = 0;
82  _v.lo = 0;
83  }
90  inline int64x64_t (const double value)
91  {
92  const int64x64_t tmp ((long double)value);
93  _v = tmp._v;
94  }
95  inline int64x64_t (const long double value)
96  {
97  const bool negative = value < 0;
98  const long double v = negative ? -value : value;
99 
100  long double fhi;
101  long double flo = std::modf (v, &fhi);
102  // Add 0.5 to round, which improves the last count
103  // This breaks these tests:
104  // TestSuite devices-mesh-dot11s-regression
105  // TestSuite devices-mesh-flame-regression
106  // TestSuite routing-aodv-regression
107  // TestSuite routing-olsr-regression
108  // Setting round = 0; breaks:
109  // TestSuite int64x64
110  const long double round = 0.5;
111  flo = flo * HP_MAX_64 + round;
112  cairo_int64_t hi = (cairo_int64_t)fhi;
113  const cairo_uint64_t lo = (cairo_uint64_t)flo;
114  if (flo >= HP_MAX_64)
115  {
116  // conversion to uint64 rolled over
117  ++hi;
118  }
119  _v.hi = hi;
120  _v.lo = lo;
121  _v = negative ? _cairo_int128_negate (_v) : _v;
122  }
131  inline int64x64_t (const int v)
132  {
133  _v.hi = v;
134  _v.lo = 0;
135  }
136  inline int64x64_t (const long int v)
137  {
138  _v.hi = v;
139  _v.lo = 0;
140  }
141  inline int64x64_t (const long long int v)
142  {
143  _v.hi = v;
144  _v.lo = 0;
145  }
146  inline int64x64_t (const unsigned int v)
147  {
148  _v.hi = v;
149  _v.lo = 0;
150  }
151  inline int64x64_t (const unsigned long int v)
152  {
153  _v.hi = v;
154  _v.lo = 0;
155  }
156  inline int64x64_t (const unsigned long long int v)
157  {
158  _v.hi = v;
159  _v.lo = 0;
160  }
168  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
169  {
170  _v.hi = hi;
171  _v.lo = lo;
172  }
173 
179  inline int64x64_t (const int64x64_t & o)
180  : _v (o._v)
181  {}
188  inline int64x64_t & operator = (const int64x64_t & o)
189  {
190  _v = o._v;
191  return *this;
192  }
193 
199  inline double GetDouble (void) const
200  {
201  const bool negative = _cairo_int128_negative (_v);
202  const cairo_int128_t value = negative ? _cairo_int128_negate (_v) : _v;
203  const long double fhi = static_cast<long double> (value.hi);
204  const long double flo = value.lo / HP_MAX_64;
205  long double retval = fhi;
206  retval += flo;
207  retval = negative ? -retval : retval;
208  return static_cast<double> (retval);
209  }
215  inline int64_t GetHigh (void) const
216  {
217  return (int64_t)_v.hi;
218  }
224  inline uint64_t GetLow (void) const
225  {
226  return _v.lo;
227  }
228 
234  int64_t GetInt (void) const
235  {
236  const bool negative = _cairo_int128_negative (_v);
237  const cairo_int128_t value = negative ? _cairo_int128_negate (_v) : _v;
238  int64_t retval = value.hi;
239  retval = negative ? - retval : retval;
240  return retval;
241  }
242 
249  int64_t Round (void) const
250  {
251  const bool negative = _cairo_int128_negative (_v);
252  cairo_uint128_t value = negative ? _cairo_int128_negate (_v) : _v;
253  cairo_uint128_t half {1ULL << 63, 0}; // lo, hi
254  value = _cairo_uint128_add (value, half);
255  int64_t retval = value.hi;
256  retval = negative ? - retval : retval;
257  return retval;
258  }
259 
268  void MulByInvert (const int64x64_t & o);
269 
283  static int64x64_t Invert (const uint64_t v);
284 
285 private:
286 
298  friend bool operator == (const int64x64_t & lhs, const int64x64_t & rhs);
299 
300  friend bool operator < (const int64x64_t & lhs, const int64x64_t & rhs);
301  friend bool operator > (const int64x64_t & lhs, const int64x64_t & rhs);
302 
303  friend int64x64_t & operator += ( int64x64_t & lhs, const int64x64_t & rhs);
304  friend int64x64_t & operator -= ( int64x64_t & lhs, const int64x64_t & rhs);
305  friend int64x64_t & operator *= ( int64x64_t & lhs, const int64x64_t & rhs);
306  friend int64x64_t & operator /= ( int64x64_t & lhs, const int64x64_t & rhs);
319  friend int64x64_t operator - (const int64x64_t & lhs);
320  friend int64x64_t operator ! (const int64x64_t & lhs);
328  void Mul (const int64x64_t & o);
334  void Div (const int64x64_t & o);
359  static cairo_uint128_t Umul (const cairo_uint128_t a, const cairo_uint128_t b);
367  static cairo_uint128_t Udiv (const cairo_uint128_t a, const cairo_uint128_t b);
377  static cairo_uint128_t UmulByInvert (const cairo_uint128_t a, const cairo_uint128_t b);
378 
380 
381 }; // class int64x64_t
382 
383 
391 inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
392 {
393  return _cairo_int128_eq (lhs._v, rhs._v);
394 }
402 inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
403 {
404  return _cairo_int128_lt (lhs._v, rhs._v);
405 }
413 inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
414 {
415  return _cairo_int128_gt (lhs._v, rhs._v);
416 }
417 
425 inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
426 {
427  lhs._v = _cairo_int128_add ( lhs._v, rhs._v );
428  return lhs;
429 }
437 inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
438 {
439  lhs._v = _cairo_int128_sub ( lhs._v, rhs._v );
440  return lhs;
441 }
449 inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
450 {
451  lhs.Mul (rhs);
452  return lhs;
453 }
461 inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
462 {
463  lhs.Div (rhs);
464  return lhs;
465 }
466 
473 inline int64x64_t operator + (const int64x64_t & lhs)
474 {
475  return lhs;
476 }
483 inline int64x64_t operator - (const int64x64_t & lhs)
484 {
485  int64x64_t tmp = lhs;
486  tmp._v = _cairo_int128_negate (tmp._v);
487  return tmp;
488 }
495 inline int64x64_t operator ! (const int64x64_t & lhs)
496 {
497  return (lhs == int64x64_t ()) ? int64x64_t (1, 0) : int64x64_t ();
498 }
499 
500 
501 } // namespace ns3
502 
503 #endif /* INT64X64_CAIRO_H */
int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:443
cairo_int128_t _v
The Q64.64 value.
int64x64_t operator+(const int64x64_t &lhs)
Unary plus operator.
Definition: int64x64-128.h:491
int64x64_t(const long int v)
Construct from an integral type.
int64x64_t(const long double value)
Construct from a floating point value.
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:45
int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Compound multiplication operator.
Definition: int64x64-128.h:467
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:501
static uint128_t Udiv(const uint128_t a, const uint128_t b)
Unsigned division of Q64.64 values.
impl_type
Type tag for the underlying implementation.
Definition: int64x64-128.h:76
int64_t cairo_int64_t
void MulByInvert(const int64x64_t &o)
Multiply this value by a Q0.128 value, presumably representing an inverse, completing a division oper...
friend int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:511
int64_t Round(void) const
Round to the nearest int.
friend int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Compound multiplication operator.
Definition: int64x64-128.h:467
int64_t GetInt(void) const
Truncate to an integer.
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:409
cairo_uint128_t cairo_I _cairo_uint128_add(cairo_uint128_t a, cairo_uint128_t b)
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:160
friend int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Compound division operator.
Definition: int64x64-128.h:479
int64x64_t(const unsigned long int v)
Construct from an integral type.
static const uint64_t HP_MASK_LO
Mask for fraction part.
Definition: int64x64-128.h:50
int128_t _v
The Q64.64 value.
Definition: int64x64-128.h:397
int64x64_t(const int64_t hi, const uint64_t lo)
Construct from explicit high and low values.
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:455
int64x64_t(const long long int v)
Construct from an integral type.
int cairo_I _cairo_int128_lt(cairo_int128_t a, cairo_int128_t b)
#define _cairo_int128_eq(a, b)
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:64
int64x64_t()
Default constructor.
static uint128_t UmulByInvert(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 and Q0.128 values.
#define _cairo_int128_sub(a, b)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
#define _cairo_int128_negative(a)
int64x64_t(const int v)
Construct from an integral type.
int64x64_t(const unsigned long long int v)
Construct from an integral type.
uint64_t cairo_uint64_t
#define _cairo_int128_gt(a, b)
int64x64_t & operator=(const int64x64_t &o)
Assignment.
Definition: int64x64-128.h:195
cairo_x function declarations, which provide the fallback high precision arithmetic implementation...
static uint128_t Umul(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 values.
Definition: int64x64-128.cc:73
void Div(const int64x64_t &o)
Implement /=.
Native int128_t implementation.
Definition: int64x64-128.h:78
int64x64_t(const unsigned int v)
Construct from an integral type.
friend bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Less than operator.
Definition: int64x64-128.h:420
uint64_t GetLow(void) const
Get the fractional portion of this value, unscaled.
bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Greater operator.
Definition: int64x64-128.h:431
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:142
#define _cairo_int128_negate(a)
Cairo wideint implementation.
Definition: int64x64-128.h:79
double GetDouble(void) const
Get this value as a double.
#define HP_MAX_64
Floating point value of HP_MASK_LO + 1 We really want:
static const uint64_t HPCAIRO_MASK_HI_BIT
High bit of fractional part.
int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:455
friend int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:443
#define _cairo_int128_add(a, b)
friend int64x64_t operator-(const int64x64_t &lhs)
Unary operator.
Definition: int64x64-128.h:501
int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Compound division operator.
Definition: int64x64-128.h:479
friend bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Greater operator.
Definition: int64x64-128.h:431
int64x64_t(const int64x64_t &o)
Copy constructor.
long double implementation.
Definition: int64x64-128.h:80
int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:511
int64x64_t(const double value)
Construct from a floating point value.
int64_t GetHigh(void) const
Get the integer portion.
static enum impl_type implementation
Type tag for this implementation.
Definition: int64x64-128.h:84