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 
33 namespace ns3 {
34 
40 {
42  static const uint128_t HP128_MASK_HI_BIT = (((int128_t)1)<<127);
44  static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
46  static const uint64_t HP_MASK_HI = ~HP_MASK_LO;
60 #define HP_MAX_64 (std::pow (2.0L, 64))
61 
62 public:
70  enum impl_type {
74  };
75 
77  static const enum impl_type implementation = int128_impl;
78 
80  inline int64x64_t ()
81  : _v (0) {}
88  inline int64x64_t (const double value)
89  {
90  const int64x64_t tmp ((long double)value);
91  _v = tmp._v;
92  }
93  inline int64x64_t (const long double value)
94  {
95  const bool negative = value < 0;
96  const long double v = negative ? -value : value;
97 
98  long double fhi;
99  long double flo = std::modf (v, &fhi);
100  // Add 0.5 to round, which improves the last count
101  // This breaks these tests:
102  // TestSuite devices-mesh-dot11s-regression
103  // TestSuite devices-mesh-flame-regression
104  // TestSuite routing-aodv-regression
105  // TestSuite routing-olsr-regression
106  // Setting round = 0; breaks:
107  // TestSuite int64x64
108  const long double round = 0.5;
109  flo = flo * HP_MAX_64 + round;
110  int128_t hi = fhi;
111  const uint64_t lo = flo;
112  if (flo >= HP_MAX_64)
113  {
114  // conversion to uint64 rolled over
115  ++hi;
116  }
117  _v = hi << 64;
118  _v |= lo;
119  _v = negative ? -_v : _v;
120  }
129  inline int64x64_t (const int v)
130  : _v (v)
131  {
132  _v <<= 64;
133  }
134  inline int64x64_t (const long int v)
135  : _v (v)
136  {
137  _v <<= 64;
138  }
139  inline int64x64_t (const long long int v)
140  : _v (v)
141  {
142  _v <<= 64;
143  }
144  inline int64x64_t (const unsigned int v)
145  : _v (v)
146  {
147  _v <<= 64;
148  }
149  inline int64x64_t (const unsigned long int v)
150  : _v (v)
151  {
152  _v <<= 64;
153  }
154  inline int64x64_t (const unsigned long long int v)
155  : _v (v)
156  {
157  _v <<= 64;
158  }
167  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
168  {
169  _v = (int128_t)hi << 64;
170  _v |= lo;
171  }
172 
178  inline int64x64_t (const int64x64_t & o)
179  : _v (o._v) {}
186  inline int64x64_t & operator = (const int64x64_t & o)
187  {
188  _v = o._v;
189  return *this;
190  }
191 
197  inline double GetDouble (void) const
198  {
199  const bool negative = _v < 0;
200  const uint128_t value = negative ? -_v : _v;
201  const long double fhi = value >> 64;
202  const long double flo = (value & HP_MASK_LO) / HP_MAX_64;
203  long double retval = fhi;
204  retval += flo;
205  retval = negative ? -retval : retval;
206  return retval;
207  }
213  inline int64_t GetHigh (void) const
214  {
215  const int128_t retval = _v >> 64;
216  return retval;
217  }
223  inline uint64_t GetLow (void) const
224  {
225  const uint128_t retval = _v & HP_MASK_LO;
226  return retval;
227  }
228 
237  void MulByInvert (const int64x64_t & o);
238 
252  static int64x64_t Invert (const uint64_t v);
253 
254 private:
255 
256  friend bool operator == (const int64x64_t & lhs, const int64x64_t & rhs);
257 
258  friend bool operator < (const int64x64_t & lhs, const int64x64_t & rhs);
259  friend bool operator > (const int64x64_t & lhs, const int64x64_t & rhs);
260 
261  friend int64x64_t & operator += ( int64x64_t & lhs, const int64x64_t & rhs);
262  friend int64x64_t & operator -= ( int64x64_t & lhs, const int64x64_t & rhs);
263  friend int64x64_t & operator *= ( int64x64_t & lhs, const int64x64_t & rhs);
264  friend int64x64_t & operator /= ( int64x64_t & lhs, const int64x64_t & rhs);
265 
266  friend int64x64_t operator - (const int64x64_t & lhs);
267  friend int64x64_t operator ! (const int64x64_t & lhs);
268 
274  void Mul (const int64x64_t & o);
280  void Div (const int64x64_t & o);
305  static uint128_t Umul (const uint128_t a, const uint128_t b);
313  static uint128_t Udiv (const uint128_t a, const uint128_t b);
323  static uint128_t UmulByInvert (const uint128_t a, const uint128_t b);
324 
330  inline int64x64_t (const int128_t v)
331  : _v (v) {}
332 
334 
335 }; // class int64x64_t
336 
337 
342 inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
343 {
344  return lhs._v == rhs._v;
345 }
350 inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
351 {
352  return lhs._v < rhs._v;
353 }
358 inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
359 {
360  return lhs._v > rhs._v;
361 }
362 
367 inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
368 {
369  lhs._v += rhs._v;
370  return lhs;
371 }
376 inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
377 {
378  lhs._v -= rhs._v;
379  return lhs;
380 }
385 inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
386 {
387  lhs.Mul (rhs);
388  return lhs;
389 }
394 inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
395 {
396  lhs.Div (rhs);
397  return lhs;
398 }
399 
404 inline int64x64_t operator + (const int64x64_t & lhs)
405 {
406  return lhs;
407 }
412 inline int64x64_t operator - (const int64x64_t & lhs)
413 {
414  return int64x64_t (-lhs._v);
415 }
420 inline int64x64_t operator ! (const int64x64_t & lhs)
421 {
422  return int64x64_t (!lhs._v);
423 }
424 
425 
426 } // namespace ns3
427 
428 #endif /* INT64X64_128_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(const long int v)
Definition: int64x64-128.h:134
int64x64_t(const int128_t v)
Construct from an integral type.
Definition: int64x64-128.h:330
int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Compound division operator.
Definition: int64x64-128.h:394
int64x64_t(const long double value)
Definition: int64x64-128.h:93
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:39
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
__int128_t int128_t
Definition: int64x64-128.h:30
int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Compound addition operator.
Definition: int64x64-128.h:367
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
__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:394
int64x64_t(const unsigned long int v)
Definition: int64x64-128.h:149
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
int64x64_t(const int64_t hi, const uint64_t lo)
Construct from explicit high and low values.
Definition: int64x64-128.h:167
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:376
int64x64_t(const long long int v)
Definition: int64x64-128.h:139
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
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
int64x64_t(const int v)
Definition: int64x64-128.h:129
int64x64_t(const unsigned long long int v)
Definition: int64x64-128.h:154
static const uint128_t HP128_MASK_HI_BIT
uint128_t high bit (sign bit).
Definition: int64x64-128.h:42
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 /=.
int64x64_t(const unsigned int v)
Definition: int64x64-128.h:144
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
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
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
static const uint64_t HP_MASK_HI
Mask for sign + integer part.
Definition: int64x64-128.h:46
int64x64_t(const int64x64_t &o)
Copy constructor.
Definition: int64x64-128.h:178
int64x64_t operator!(const int64x64_t &lhs)
Logical not operator.
Definition: int64x64-128.h:420
int64x64_t(const double value)
Definition: int64x64-128.h:88
int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Compound subtraction operator.
Definition: int64x64-128.h:376