A Discrete-Event Network Simulator
API
int64x64-128.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 
22 #if !defined(INT64X64_128_H) && defined (INT64X64_USE_128) && !defined(PYTHON_SCAN)
23 #define INT64X64_128_H
24 
25 #include <stdint.h>
26 #include <cmath> // pow
27 
28 #if defined(HAVE___UINT128_T) && !defined(HAVE_UINT128_T)
29 typedef __uint128_t uint128_t;
30 typedef __int128_t int128_t;
31 #endif
32 
39 namespace ns3 {
40 
46 {
48  static const uint128_t HP128_MASK_HI_BIT = (((int128_t)1) << 127);
50  static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
52  static const uint64_t HP_MASK_HI = ~HP_MASK_LO;
66 #define HP_MAX_64 (std::pow (2.0L, 64))
67 
68 public:
76  enum impl_type
77  {
81  };
82 
84  static const enum impl_type implementation = int128_impl;
85 
87  inline int64x64_t ()
88  : _v (0)
89  {}
96  inline int64x64_t (const double value)
97  {
98  const int64x64_t tmp ((long double)value);
99  _v = tmp._v;
100  }
101  inline int64x64_t (const long double value)
102  {
103  const bool negative = value < 0;
104  const long double v = negative ? -value : value;
105 
106  long double fhi;
107  long double flo = std::modf (v, &fhi);
108  // Add 0.5 to round, which improves the last count
109  // This breaks these tests:
110  // TestSuite devices-mesh-dot11s-regression
111  // TestSuite devices-mesh-flame-regression
112  // TestSuite routing-aodv-regression
113  // TestSuite routing-olsr-regression
114  // Setting round = 0; breaks:
115  // TestSuite int64x64
116  const long double round = 0.5;
117  flo = flo * HP_MAX_64 + round;
118  int128_t hi = fhi;
119  const uint64_t lo = flo;
120  if (flo >= HP_MAX_64)
121  {
122  // conversion to uint64 rolled over
123  ++hi;
124  }
125  _v = hi << 64;
126  _v |= lo;
127  _v = negative ? -_v : _v;
128  }
137  inline int64x64_t (const int v)
138  : _v (v)
139  {
140  _v <<= 64;
141  }
142  inline int64x64_t (const long int v)
143  : _v (v)
144  {
145  _v <<= 64;
146  }
147  inline int64x64_t (const long long int v)
148  : _v (v)
149  {
150  _v <<= 64;
151  }
152  inline int64x64_t (const unsigned int v)
153  : _v (v)
154  {
155  _v <<= 64;
156  }
157  inline int64x64_t (const unsigned long int v)
158  : _v (v)
159  {
160  _v <<= 64;
161  }
162  inline int64x64_t (const unsigned long long int v)
163  : _v (v)
164  {
165  _v <<= 64;
166  }
175  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
176  {
177  _v = (int128_t)hi << 64;
178  _v |= lo;
179  }
180 
186  inline int64x64_t (const int64x64_t & o)
187  : _v (o._v)
188  {}
195  inline int64x64_t & operator = (const int64x64_t & o)
196  {
197  _v = o._v;
198  return *this;
199  }
200 
206  inline double GetDouble (void) const
207  {
208  const bool negative = _v < 0;
209  const uint128_t value = negative ? -_v : _v;
210  const long double fhi = value >> 64;
211  const long double flo = (value & HP_MASK_LO) / HP_MAX_64;
212  long double retval = fhi;
213  retval += flo;
214  retval = negative ? -retval : retval;
215  return retval;
216  }
222  inline int64_t GetHigh (void) const
223  {
224  const int128_t retval = _v >> 64;
225  return retval;
226  }
232  inline uint64_t GetLow (void) const
233  {
234  const uint128_t retval = _v & HP_MASK_LO;
235  return retval;
236  }
237 
243  int64_t GetInt (void) const
244  {
245  const bool negative = _v < 0;
246  const uint128_t value = negative ? -_v : _v;
247  int64_t retval = value >> 64;
248  retval = negative ? - retval : retval;
249  return retval;
250  }
251 
258  int64_t Round (void) const
259  {
260  const bool negative = _v < 0;
261  int64x64_t value = (negative ? -(*this) : *this);
262  const int64x64_t half (0, 1LL << 63);
263  value += half;
264  int64_t retval = value.GetHigh ();
265  retval = negative ? - retval : retval;
266  return retval;
267  }
268 
277  void MulByInvert (const int64x64_t & o);
278 
292  static int64x64_t Invert (const uint64_t v);
293 
294 private:
295 
307  friend bool operator == (const int64x64_t & lhs, const int64x64_t & rhs);
308 
309  friend bool operator < (const int64x64_t & lhs, const int64x64_t & rhs);
310  friend bool operator > (const int64x64_t & lhs, const int64x64_t & rhs);
311 
312  friend int64x64_t & operator += ( int64x64_t & lhs, const int64x64_t & rhs);
313  friend int64x64_t & operator -= ( int64x64_t & lhs, const int64x64_t & rhs);
314  friend int64x64_t & operator *= ( int64x64_t & lhs, const int64x64_t & rhs);
315  friend int64x64_t & operator /= ( int64x64_t & lhs, const int64x64_t & rhs);
328  friend int64x64_t operator - (const int64x64_t & lhs);
329  friend int64x64_t operator ! (const int64x64_t & lhs);
337  void Mul (const int64x64_t & o);
343  void Div (const int64x64_t & o);
368  static uint128_t Umul (const uint128_t a, const uint128_t b);
376  static uint128_t Udiv (const uint128_t a, const uint128_t b);
386  static uint128_t UmulByInvert (const uint128_t a, const uint128_t b);
387 
393  inline int64x64_t (const int128_t v)
394  : _v (v)
395  {}
396 
398 
399 }; // class int64x64_t
400 
401 
409 inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
410 {
411  return lhs._v == rhs._v;
412 }
420 inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
421 {
422  return lhs._v < rhs._v;
423 }
431 inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
432 {
433  return lhs._v > rhs._v;
434 }
435 
443 inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
444 {
445  lhs._v += rhs._v;
446  return lhs;
447 }
455 inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
456 {
457  lhs._v -= rhs._v;
458  return lhs;
459 }
467 inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
468 {
469  lhs.Mul (rhs);
470  return lhs;
471 }
479 inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
480 {
481  lhs.Div (rhs);
482  return lhs;
483 }
484 
491 inline int64x64_t operator + (const int64x64_t & lhs)
492 {
493  return lhs;
494 }
501 inline int64x64_t operator - (const int64x64_t & lhs)
502 {
503  return int64x64_t (-lhs._v);
504 }
511 inline int64x64_t operator ! (const int64x64_t & lhs)
512 {
513  return int64x64_t (!lhs._v);
514 }
515 
516 
517 } // namespace ns3
518 
519 #endif /* INT64X64_128_H */
int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:443
int64x64_t operator+(const int64x64_t &lhs)
Unary plus operator.
Definition: int64x64-128.h:491
int64x64_t(const long int v)
Definition: int64x64-128.h:142
int64x64_t(const int128_t v)
Construct from an integral type.
Definition: int64x64-128.h:393
int64x64_t(const long double value)
Definition: int64x64-128.h:101
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
__int128_t int128_t
Definition: int64x64-128.h:30
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.
Definition: int64x64-128.h:258
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.
Definition: int64x64-128.h:243
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:409
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:160
__uint128_t uint128_t
Definition: int64x64-128.h:29
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)
Definition: int64x64-128.h:157
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.
Definition: int64x64-128.h:175
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)
Definition: int64x64-128.h:147
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:64
int64x64_t()
Default constructor.
Definition: int64x64-128.h:87
static uint128_t UmulByInvert(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 and Q0.128 values.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
int64x64_t(const int v)
Definition: int64x64-128.h:137
int64x64_t(const unsigned long long int v)
Definition: int64x64-128.h:162
static const uint128_t HP128_MASK_HI_BIT
uint128_t high bit (sign bit).
Definition: int64x64-128.h:48
int64x64_t & operator=(const int64x64_t &o)
Assignment.
Definition: int64x64-128.h:195
#define HP_MAX_64
Floating point value of HP_MASK_LO + 1.
Definition: int64x64-128.h:66
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)
Definition: int64x64-128.h:152
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.
Definition: int64x64-128.h:232
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
Cairo wideint implementation.
Definition: int64x64-128.h:79
double GetDouble(void) const
Get this value as a double.
Definition: int64x64-128.h:206
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
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
static const uint64_t HP_MASK_HI
Mask for sign + integer part.
Definition: int64x64-128.h:52
int64x64_t(const int64x64_t &o)
Copy constructor.
Definition: int64x64-128.h:186
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)
Definition: int64x64-128.h:96
int64_t GetHigh(void) const
Get the integer portion.
Definition: int64x64-128.h:222
static enum impl_type implementation
Type tag for this implementation.
Definition: int64x64-128.h:84