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 
28 
29 namespace ns3 {
30 
35 class int64x64_t
36 {
38  static const uint64_t HPCAIRO_MASK_HI_BIT = (((uint64_t)1)<<63);
40  static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
53 #define HP_MAX_64 (std::pow (2.0L, 64))
54 
55 public:
63  enum impl_type {
64  int128_impl,
65  cairo_impl,
66  ld_impl,
67  };
68 
70  static const enum impl_type implementation = cairo_impl;
71 
73  inline int64x64_t ()
74  {
75  _v.hi = 0;
76  _v.lo = 0;
77  }
84  inline int64x64_t (const double value)
85  {
86  const int64x64_t tmp ((long double)value);
87  _v = tmp._v;
88  }
89  inline int64x64_t (const long double value)
90  {
91  const bool negative = value < 0;
92  const long double v = negative ? -value : value;
93 
94  long double fhi;
95  long double flo = std::modf (v, &fhi);
96  // Add 0.5 to round, which improves the last count
97  // This breaks these tests:
98  // TestSuite devices-mesh-dot11s-regression
99  // TestSuite devices-mesh-flame-regression
100  // TestSuite routing-aodv-regression
101  // TestSuite routing-olsr-regression
102  // Setting round = 0; breaks:
103  // TestSuite int64x64
104  const long double round = 0.5;
105  flo = flo * HP_MAX_64 + round;
106  cairo_int64_t hi = fhi;
107  const cairo_uint64_t lo = flo;
108  if (flo >= HP_MAX_64)
109  {
110  // conversion to uint64 rolled over
111  ++hi;
112  }
113  _v.hi = hi;
114  _v.lo = lo;
115  _v = negative ? _cairo_int128_negate (_v) : _v;
116  }
125  inline int64x64_t (const int v)
126  {
127  _v.hi = v;
128  _v.lo = 0;
129  }
130  inline int64x64_t (const long int v)
131  {
132  _v.hi = v;
133  _v.lo = 0;
134  }
135  inline int64x64_t (const long long int v)
136  {
137  _v.hi = v;
138  _v.lo = 0;
139  }
140  inline int64x64_t (const unsigned int v)
141  {
142  _v.hi = v;
143  _v.lo = 0;
144  }
145  inline int64x64_t (const unsigned long int v)
146  {
147  _v.hi = v;
148  _v.lo = 0;
149  }
150  inline int64x64_t (const unsigned long long int v)
151  {
152  _v.hi = v;
153  _v.lo = 0;
154  }
162  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
163  {
164  _v.hi = hi;
165  _v.lo = lo;
166  }
167 
173  inline int64x64_t (const int64x64_t & o)
174  : _v (o._v) {}
180  inline int64x64_t & operator = (const int64x64_t & o)
181  {
182  _v = o._v;
183  return *this;
184  }
185 
191  inline double GetDouble (void) const
192  {
193  const bool negative = _cairo_int128_negative (_v);
194  const cairo_int128_t value = negative ? _cairo_int128_negate (_v) : _v;
195  const long double fhi = value.hi;
196  const long double flo = value.lo / HP_MAX_64;
197  long double retval = fhi;
198  retval += flo;
199  retval = negative ? -retval : retval;
200  return retval;
201  }
207  inline int64_t GetHigh (void) const
208  {
209  return (int64_t)_v.hi;
210  }
216  inline uint64_t GetLow (void) const
217  {
218  return _v.lo;
219  }
220 
229  void MulByInvert (const int64x64_t & o);
230 
244  static int64x64_t Invert (const uint64_t v);
245 
246 private:
247  friend bool operator == (const int64x64_t & lhs, const int64x64_t & rhs);
248 
249  friend bool operator < (const int64x64_t & lhs, const int64x64_t & rhs);
250  friend bool operator > (const int64x64_t & lhs, const int64x64_t & rhs);
251 
252  friend int64x64_t & operator += ( int64x64_t & lhs, const int64x64_t & rhs);
253  friend int64x64_t & operator -= ( int64x64_t & lhs, const int64x64_t & rhs);
254  friend int64x64_t & operator *= ( int64x64_t & lhs, const int64x64_t & rhs);
255  friend int64x64_t & operator /= ( int64x64_t & lhs, const int64x64_t & rhs);
256 
257  friend int64x64_t operator - (const int64x64_t & lhs);
258  friend int64x64_t operator ! (const int64x64_t & lhs);
259 
265  void Mul (const int64x64_t & o);
271  void Div (const int64x64_t & o);
296  static cairo_uint128_t Umul (const cairo_uint128_t a, const cairo_uint128_t b);
304  static cairo_uint128_t Udiv (const cairo_uint128_t a, const cairo_uint128_t b);
314  static cairo_uint128_t UmulByInvert (const cairo_uint128_t a, const cairo_uint128_t b);
315 
317 
318 }; // class int64x64_t
319 
320 
325 inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
326 {
327  return _cairo_int128_eq (lhs._v, rhs._v);
328 }
333 inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
334 {
335  return _cairo_int128_lt (lhs._v, rhs._v);
336 }
341 inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
342 {
343  return _cairo_int128_gt (lhs._v, rhs._v);
344 }
345 
350 inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
351 {
352  lhs._v = _cairo_int128_add( lhs._v, rhs._v );
353  return lhs;
354 }
359 inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
360 {
361  lhs._v = _cairo_int128_sub( lhs._v, rhs._v );
362  return lhs;
363 }
368 inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
369 {
370  lhs.Mul (rhs);
371  return lhs;
372 }
377 inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
378 {
379  lhs.Div (rhs);
380  return lhs;
381 }
382 
387 inline int64x64_t operator + (const int64x64_t & lhs)
388 {
389  return lhs;
390 }
395 inline int64x64_t operator - (const int64x64_t & lhs)
396 {
397  int64x64_t tmp = lhs;
398  tmp._v = _cairo_int128_negate (tmp._v);
399  return tmp;
400 }
405 inline int64x64_t operator ! (const int64x64_t & lhs)
406 {
407  return (lhs == int64x64_t ()) ? int64x64_t (1, 0) : int64x64_t ();
408 }
409 
410 
411 } // namespace ns3
412 
413 #endif /* INT64X64_CAIRO_H */
long double implementation.
Definition: int64x64-128.h:73
uint64_t GetLow(void) const
Get the fractional portion of this value, unscaled.
Definition: int64x64-128.h:223
int64x64_t operator+(const int64x64_t &lhs)
Unary plus operator.
Definition: int64x64-128.h:404
int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Compound division operator.
Definition: int64x64-128.h:394
static uint128_t Udiv(const uint128_t a, const uint128_t b)
Unsigned division of Q64.64 values.
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:412
impl_type
Type tag for the underlying implementation.
Definition: int64x64-128.h:70
int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:367
int64_t cairo_int64_t
static enum impl_type implementation
Type tag for this implementation.
Definition: int64x64-128.h:77
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:197
friend int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:420
friend int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Compound multiplication operator.
Definition: int64x64-128.h:385
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Equality operator.
Definition: int64x64-128.h:342
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:394
static uint128_t Umul(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 values.
Definition: int64x64-128.cc:67
int128_t _v
The Q64.64 value.
Definition: int64x64-128.h:333
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:376
#define _cairo_int128_eq(a, b)
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:58
int64x64_t()
Default constructor.
Definition: int64x64-128.h:80
bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Less than operator.
Definition: int64x64-128.h:350
#define _cairo_int128_sub(a, b)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Compound multiplication operator.
Definition: int64x64-128.h:385
#define _cairo_int128_negative(a)
uint64_t cairo_uint64_t
#define _cairo_int128_gt(a, b)
Native int128_t implementation.
Definition: int64x64-128.h:71
static const uint64_t HP_MASK_LO
Mask for fraction part.
Definition: int64x64-128.h:44
int64x64_t & operator=(const int64x64_t &o)
Assignment.
Definition: int64x64-128.h:186
#define HP_MAX_64
Floating point value of HP_MASK_LO + 1.
Definition: int64x64-128.h:60
void Div(const int64x64_t &o)
Implement /=.
friend bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Less than operator.
Definition: int64x64-128.h:350
bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Greater operator.
Definition: int64x64-128.h:358
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:95
#define _cairo_int128_negate(a)
int64_t GetHigh(void) const
Get the integer portion.
Definition: int64x64-128.h:213
Cairo wideint implementation.
Definition: int64x64-128.h:72
friend int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:367
#define _cairo_int128_add(a, b)
friend int64x64_t operator-(const int64x64_t &lhs)
Unary negation operator (change sign operator).
Definition: int64x64-128.h:412
friend bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Greater operator.
Definition: int64x64-128.h:358
int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:420
int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:376