A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
int64x64-128.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19#include "ns3/core-config.h"
20
21#if !defined(INT64X64_128_H) && defined(INT64X64_USE_128) && !defined(PYTHON_SCAN)
26#define INT64X64_128_H
27
28#include <cmath> // pow
29#include <stdint.h>
30
31#if defined(HAVE___UINT128_T) && !defined(HAVE_UINT128_T)
37typedef __uint128_t uint128_t;
38typedef __int128_t int128_t;
40#endif
41
48namespace ns3
49{
50
56{
58 static const uint128_t HP128_MASK_HI_BIT = (((int128_t)1) << 127);
60 static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
62 static const uint64_t HP_MASK_HI = ~HP_MASK_LO;
76#define HP_MAX_64 (std::pow(2.0L, 64))
77
78 public:
87 {
91 };
92
95
97 inline int64x64_t()
98 : _v(0)
99 {
100 }
101
111 inline int64x64_t(const double value)
112 {
113 const int64x64_t tmp((long double)value);
114 _v = tmp._v;
115 }
116
117 inline int64x64_t(const long double value)
118 {
119 const bool negative = value < 0;
120 const long double v = negative ? -value : value;
121
122 long double fhi;
123 long double flo = std::modf(v, &fhi);
124 // Add 0.5 to round, which improves the last count
125 // This breaks these tests:
126 // TestSuite devices-mesh-dot11s-regression
127 // TestSuite devices-mesh-flame-regression
128 // TestSuite routing-aodv-regression
129 // TestSuite routing-olsr-regression
130 // Setting round = 0; breaks:
131 // TestSuite int64x64
132 const long double round = 0.5;
133 flo = flo * HP_MAX_64 + round;
134 int128_t hi = fhi;
135 const uint64_t lo = flo;
136 if (flo >= HP_MAX_64)
137 {
138 // conversion to uint64 rolled over
139 ++hi;
140 }
141 _v = hi << 64;
142 _v |= lo;
143 _v = negative ? -_v : _v;
144 }
145
157 inline int64x64_t(const int v)
158 : _v(v)
159 {
160 _v <<= 64;
161 }
162
163 inline int64x64_t(const long int v)
164 : _v(v)
165 {
166 _v <<= 64;
167 }
168
169 inline int64x64_t(const long long int v)
170 : _v(v)
171 {
172 _v <<= 64;
173 }
174
175 inline int64x64_t(const unsigned int v)
176 : _v(v)
177 {
178 _v <<= 64;
179 }
180
181 inline int64x64_t(const unsigned long int v)
182 : _v(v)
183 {
184 _v <<= 64;
185 }
186
187 inline int64x64_t(const unsigned long long int v)
188 : _v(v)
189 {
190 _v <<= 64;
191 }
192
201 explicit inline int64x64_t(const int64_t hi, const uint64_t lo)
202 {
203 _v = (int128_t)hi << 64;
204 _v |= lo;
205 }
206
212 inline int64x64_t(const int64x64_t& o)
213 : _v(o._v)
214 {
215 }
216
224 {
225 _v = o._v;
226 return *this;
227 }
228
230 inline explicit operator bool() const
231 {
232 return (_v != 0);
233 }
234
240 inline double GetDouble() const
241 {
242 const bool negative = _v < 0;
243 const uint128_t value = negative ? -_v : _v;
244 const long double fhi = value >> 64;
245 const long double flo = (value & HP_MASK_LO) / HP_MAX_64;
246 long double retval = fhi;
247 retval += flo;
248 retval = negative ? -retval : retval;
249 return retval;
250 }
251
257 inline int64_t GetHigh() const
258 {
259 const int128_t retval = _v >> 64;
260 return retval;
261 }
262
268 inline uint64_t GetLow() const
269 {
270 const uint128_t retval = _v & HP_MASK_LO;
271 return retval;
272 }
273
279 int64_t GetInt() const
280 {
281 const bool negative = _v < 0;
282 const uint128_t value = negative ? -_v : _v;
283 int64_t retval = value >> 64;
284 retval = negative ? -retval : retval;
285 return retval;
286 }
287
294 int64_t Round() const
295 {
296 const bool negative = _v < 0;
297 int64x64_t value = (negative ? -(*this) : *this);
298 const int64x64_t half(0, 1LL << 63);
299 value += half;
300 int64_t retval = value.GetHigh();
301 retval = negative ? -retval : retval;
302 return retval;
303 }
304
313 void MulByInvert(const int64x64_t& o);
314
328 static int64x64_t Invert(const uint64_t v);
329
330 private:
343 friend inline bool operator==(const int64x64_t& lhs, const int64x64_t& rhs)
344 {
345 return lhs._v == rhs._v;
346 }
347
348 friend inline bool operator<(const int64x64_t& lhs, const int64x64_t& rhs)
349 {
350 return lhs._v < rhs._v;
351 }
352
353 friend inline bool operator>(const int64x64_t& lhs, const int64x64_t& rhs)
354 {
355 return lhs._v > rhs._v;
356 }
357
358 friend inline int64x64_t& operator+=(int64x64_t& lhs, const int64x64_t& rhs)
359 {
360 lhs._v += rhs._v;
361 return lhs;
362 }
363
364 friend inline int64x64_t& operator-=(int64x64_t& lhs, const int64x64_t& rhs)
365 {
366 lhs._v -= rhs._v;
367 return lhs;
368 }
369
370 friend inline int64x64_t& operator*=(int64x64_t& lhs, const int64x64_t& rhs)
371 {
372 lhs.Mul(rhs);
373 return lhs;
374 }
375
376 friend inline int64x64_t& operator/=(int64x64_t& lhs, const int64x64_t& rhs)
377 {
378 lhs.Div(rhs);
379 return lhs;
380 }
381
394 friend inline int64x64_t operator+(const int64x64_t& lhs)
395 {
396 return lhs;
397 }
398
399 friend inline int64x64_t operator-(const int64x64_t& lhs)
400 {
401 int64x64_t res;
402 res._v = -lhs._v;
403 return res;
404 }
405
406 friend inline int64x64_t operator!(const int64x64_t& lhs)
407 {
408 return int64x64_t(!lhs._v);
409 }
410
418 void Mul(const int64x64_t& o);
424 void Div(const int64x64_t& o);
449 static uint128_t Umul(const uint128_t a, const uint128_t b);
457 static uint128_t Udiv(const uint128_t a, const uint128_t b);
467 static uint128_t UmulByInvert(const uint128_t a, const uint128_t b);
468
470
471}; // class int64x64_t
472
473} // namespace ns3
474
475#endif /* INT64X64_128_H */
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:56
int64_t GetHigh() const
Get the integer portion.
Definition: int64x64-128.h:257
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:343
static const uint64_t HP_MASK_LO
Mask for fraction part.
Definition: int64x64-128.h:60
static const uint128_t HP128_MASK_HI_BIT
uint128_t high bit (sign bit).
Definition: int64x64-128.h:58
impl_type
Type tag for the underlying implementation.
Definition: int64x64-128.h:87
@ int128_impl
Native int128_t implementation.
Definition: int64x64-128.h:88
@ ld_impl
long double implementation.
Definition: int64x64-128.h:90
@ cairo_impl
Cairo wideint implementation.
Definition: int64x64-128.h:89
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:364
friend int64x64_t operator+(const int64x64_t &lhs)
Unary operator.
Definition: int64x64-128.h:394
int64_t Round() const
Round to the nearest int.
Definition: int64x64-128.h:294
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:61
static uint128_t Udiv(const uint128_t a, const uint128_t b)
Unsigned division of Q64.64 values.
void MulByInvert(const int64x64_t &o)
Multiply this value by a Q0.128 value, presumably representing an inverse, completing a division oper...
friend bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:348
int64x64_t(const long double value)
Constructor from a floating point.
Definition: int64x64-128.h:117
static const uint64_t HP_MASK_HI
Mask for sign + integer part.
Definition: int64x64-128.h:62
static uint128_t UmulByInvert(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 and Q0.128 values.
static enum impl_type implementation
Type tag for this implementation.
Definition: int64x64-128.h:94
friend int64x64_t operator!(const int64x64_t &lhs)
Unary operator.
Definition: int64x64-128.h:406
int128_t _v
The Q64.64 value.
Definition: int64x64-128.h:469
friend int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:370
int64x64_t(const int64_t hi, const uint64_t lo)
Construct from explicit high and low values.
Definition: int64x64-128.h:201
void Div(const int64x64_t &o)
Implement /=.
int64x64_t(const unsigned long long int v)
Construct from an integral type.
Definition: int64x64-128.h:187
int64x64_t(const unsigned int v)
Construct from an integral type.
Definition: int64x64-128.h:175
int64x64_t(const long int v)
Construct from an integral type.
Definition: int64x64-128.h:163
int64x64_t(const long long int v)
Construct from an integral type.
Definition: int64x64-128.h:169
double GetDouble() const
Get this value as a double.
Definition: int64x64-128.h:240
friend int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:358
int64x64_t(const unsigned long int v)
Construct from an integral type.
Definition: int64x64-128.h:181
int64_t GetInt() const
Truncate to an integer.
Definition: int64x64-128.h:279
int64x64_t & operator=(const int64x64_t &o)
Assignment.
Definition: int64x64-128.h:223
friend bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:353
int64x64_t(const int v)
Construct from an integral type.
Definition: int64x64-128.h:157
uint64_t GetLow() const
Get the fractional portion of this value, unscaled.
Definition: int64x64-128.h:268
friend int64x64_t operator-(const int64x64_t &lhs)
Unary operator.
Definition: int64x64-128.h:399
static int64x64_t Invert(const uint64_t v)
Compute the inverse of an integer value.
int64x64_t(const double value)
Constructor from a floating point.
Definition: int64x64-128.h:111
int64x64_t(const int64x64_t &o)
Copy constructor.
Definition: int64x64-128.h:212
friend int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:376
int64x64_t()
Default constructor.
Definition: int64x64-128.h:97
static uint128_t Umul(const uint128_t a, const uint128_t b)
Unsigned multiplication of Q64.64 values.
Definition: int64x64-128.cc:71
__uint128_t uint128_t
Some compilers do not have this defined, so we define it.
Definition: int64x64-128.h:37
__int128_t int128_t
Some compilers do not have this defined, so we define it.
Definition: int64x64-128.h:38
#define HP_MAX_64
Floating point value of HP_MASK_LO + 1.
Definition: int64x64-128.h:76
Every class exported by the ns3 library is enclosed in the ns3 namespace.