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
55class int64x64_t
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:
86 enum impl_type
87 {
90 ld_impl,
91 };
92
94 static const enum impl_type implementation = int128_impl;
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
193 inline int64x64_t(const int128_t v)
194 : _v(v)
195 {
196 }
197
206 explicit inline int64x64_t(const int64_t hi, const uint64_t lo)
207 {
208 _v = (int128_t)hi << 64;
209 _v |= lo;
210 }
211
217 inline int64x64_t(const int64x64_t& o)
218 : _v(o._v)
219 {
220 }
221
228 inline int64x64_t& operator=(const int64x64_t& o)
229 {
230 _v = o._v;
231 return *this;
232 }
233
235 inline explicit operator bool() const
236 {
237 return (_v != 0);
238 }
239
245 inline double GetDouble() const
246 {
247 const bool negative = _v < 0;
248 const uint128_t value = negative ? -_v : _v;
249 const long double fhi = value >> 64;
250 const long double flo = (value & HP_MASK_LO) / HP_MAX_64;
251 long double retval = fhi;
252 retval += flo;
253 retval = negative ? -retval : retval;
254 return retval;
255 }
256
262 inline int64_t GetHigh() const
263 {
264 const int128_t retval = _v >> 64;
265 return retval;
266 }
267
273 inline uint64_t GetLow() const
274 {
275 const uint128_t retval = _v & HP_MASK_LO;
276 return retval;
277 }
278
284 int64_t GetInt() const
285 {
286 const bool negative = _v < 0;
287 const uint128_t value = negative ? -_v : _v;
288 int64_t retval = value >> 64;
289 retval = negative ? -retval : retval;
290 return retval;
291 }
292
299 int64_t Round() const
300 {
301 const bool negative = _v < 0;
302 int64x64_t value = (negative ? -(*this) : *this);
303 const int64x64_t half(0, 1LL << 63);
304 value += half;
305 int64_t retval = value.GetHigh();
306 retval = negative ? -retval : retval;
307 return retval;
308 }
309
318 void MulByInvert(const int64x64_t& o);
319
333 static int64x64_t Invert(const uint64_t v);
334
335 private:
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 bool operator>(const int64x64_t& lhs, const int64x64_t& rhs)
359 {
360 return lhs._v > rhs._v;
361 }
362
363 friend inline int64x64_t& operator+=(int64x64_t& lhs, const int64x64_t& rhs)
364 {
365 lhs._v += rhs._v;
366 return lhs;
367 }
368
369 friend inline int64x64_t& operator-=(int64x64_t& lhs, const int64x64_t& rhs)
370 {
371 lhs._v -= rhs._v;
372 return lhs;
373 }
374
375 friend inline int64x64_t& operator*=(int64x64_t& lhs, const int64x64_t& rhs)
376 {
377 lhs.Mul(rhs);
378 return lhs;
379 }
380
381 friend inline int64x64_t& operator/=(int64x64_t& lhs, const int64x64_t& rhs)
382 {
383 lhs.Div(rhs);
384 return lhs;
385 }
386
399 friend inline int64x64_t operator+(const int64x64_t& lhs)
400 {
401 return lhs;
402 }
403
404 friend inline int64x64_t operator-(const int64x64_t& lhs)
405 {
406 return int64x64_t(-lhs._v);
407 }
408
409 friend inline int64x64_t operator!(const int64x64_t& lhs)
410 {
411 return int64x64_t(!lhs._v);
412 }
413
421 void Mul(const int64x64_t& o);
427 void Div(const int64x64_t& o);
452 static uint128_t Umul(const uint128_t a, const uint128_t b);
460 static uint128_t Udiv(const uint128_t a, const uint128_t b);
470 static uint128_t UmulByInvert(const uint128_t a, const uint128_t b);
471
472 int128_t _v;
473
474}; // class int64x64_t
475
476} // namespace ns3
477
478#endif /* INT64X64_128_H */
int64_t GetHigh() const
Get the integer portion.
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
static const uint64_t HP_MASK_LO
Mask for fraction part.
static cairo_uint128_t Umul(const cairo_uint128_t a, const cairo_uint128_t b)
Unsigned multiplication of Q64.64 values.
Definition: int64x64-128.cc:71
impl_type
Type tag for the underlying implementation.
@ int128_impl
Native int128_t implementation.
@ ld_impl
long double implementation
@ cairo_impl
cairo wideint implementation
static cairo_uint128_t UmulByInvert(const cairo_uint128_t a, const cairo_uint128_t b)
Unsigned multiplication of Q64.64 and Q0.128 values.
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
friend int64x64_t operator+(const int64x64_t &lhs)
Unary operator.
int64_t Round() const
Round to the nearest int.
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:61
void MulByInvert(const int64x64_t &o)
Multiply this value by a Q0.128 value, presumably representing an inverse, completing a division oper...
static cairo_uint128_t Udiv(const cairo_uint128_t a, const cairo_uint128_t b)
Unsigned division of Q64.64 values.
friend bool operator<(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
static enum impl_type implementation
Type tag for this implementation.
friend int64x64_t operator!(const int64x64_t &lhs)
Unary operator.
cairo_int128_t _v
The Q64.64 value.
friend int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
void Div(const int64x64_t &o)
Implement /=.
double GetDouble() const
Get this value as a double.
friend int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
int64_t GetInt() const
Truncate to an integer.
int64x64_t & operator=(const int64x64_t &o)
Assignment.
friend bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
uint64_t GetLow() const
Get the fractional portion of this value, unscaled.
friend int64x64_t operator-(const int64x64_t &lhs)
Unary operator.
static int64x64_t Invert(const uint64_t v)
Compute the inverse of an integer value.
friend int64x64_t & operator/=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
int64x64_t()
Default constructor.
#define HP_MAX_64
Floating point value of HP_MASK_LO + 1 We really want:
Every class exported by the ns3 library is enclosed in the ns3 namespace.
value
Definition: second.py:41