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)
27 #define INT64X64_128_H
28 
29 #include <stdint.h>
30 #include <cmath> // pow
31 
32 #if defined(HAVE___UINT128_T) && !defined(HAVE_UINT128_T)
38 typedef __uint128_t uint128_t;
39 typedef __int128_t int128_t;
41 #endif
42 
49 namespace ns3 {
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:
86  enum impl_type
87  {
91  };
92 
94  static const enum impl_type implementation = int128_impl;
95 
97  inline int64x64_t ()
98  : _v (0)
99  {}
109  inline int64x64_t (const double value)
110  {
111  const int64x64_t tmp ((long double)value);
112  _v = tmp._v;
113  }
114  inline int64x64_t (const long double value)
115  {
116  const bool negative = value < 0;
117  const long double v = negative ? -value : value;
118 
119  long double fhi;
120  long double flo = std::modf (v, &fhi);
121  // Add 0.5 to round, which improves the last count
122  // This breaks these tests:
123  // TestSuite devices-mesh-dot11s-regression
124  // TestSuite devices-mesh-flame-regression
125  // TestSuite routing-aodv-regression
126  // TestSuite routing-olsr-regression
127  // Setting round = 0; breaks:
128  // TestSuite int64x64
129  const long double round = 0.5;
130  flo = flo * HP_MAX_64 + round;
131  int128_t hi = fhi;
132  const uint64_t lo = flo;
133  if (flo >= HP_MAX_64)
134  {
135  // conversion to uint64 rolled over
136  ++hi;
137  }
138  _v = hi << 64;
139  _v |= lo;
140  _v = negative ? -_v : _v;
141  }
153  inline int64x64_t (const int v)
154  : _v (v)
155  {
156  _v <<= 64;
157  }
158  inline int64x64_t (const long int v)
159  : _v (v)
160  {
161  _v <<= 64;
162  }
163  inline int64x64_t (const long long int v)
164  : _v (v)
165  {
166  _v <<= 64;
167  }
168  inline int64x64_t (const unsigned int v)
169  : _v (v)
170  {
171  _v <<= 64;
172  }
173  inline int64x64_t (const unsigned long int v)
174  : _v (v)
175  {
176  _v <<= 64;
177  }
178  inline int64x64_t (const unsigned long long int v)
179  : _v (v)
180  {
181  _v <<= 64;
182  }
183  inline int64x64_t (const int128_t v)
184  : _v (v)
185  {}
194  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
195  {
196  _v = (int128_t)hi << 64;
197  _v |= lo;
198  }
199 
205  inline int64x64_t (const int64x64_t & o)
206  : _v (o._v)
207  {}
214  inline int64x64_t & operator = (const int64x64_t & o)
215  {
216  _v = o._v;
217  return *this;
218  }
219 
221  inline explicit operator bool () const
222  {
223  return (_v != 0);
224  }
225 
231  inline double GetDouble (void) const
232  {
233  const bool negative = _v < 0;
234  const uint128_t value = negative ? -_v : _v;
235  const long double fhi = value >> 64;
236  const long double flo = (value & HP_MASK_LO) / HP_MAX_64;
237  long double retval = fhi;
238  retval += flo;
239  retval = negative ? -retval : retval;
240  return retval;
241  }
247  inline int64_t GetHigh (void) const
248  {
249  const int128_t retval = _v >> 64;
250  return retval;
251  }
257  inline uint64_t GetLow (void) const
258  {
259  const uint128_t retval = _v & HP_MASK_LO;
260  return retval;
261  }
262 
268  int64_t GetInt (void) const
269  {
270  const bool negative = _v < 0;
271  const uint128_t value = negative ? -_v : _v;
272  int64_t retval = value >> 64;
273  retval = negative ? - retval : retval;
274  return retval;
275  }
276 
283  int64_t Round (void) const
284  {
285  const bool negative = _v < 0;
286  int64x64_t value = (negative ? -(*this) : *this);
287  const int64x64_t half (0, 1LL << 63);
288  value += half;
289  int64_t retval = value.GetHigh ();
290  retval = negative ? - retval : retval;
291  return retval;
292  }
293 
302  void MulByInvert (const int64x64_t & o);
303 
317  static int64x64_t Invert (const uint64_t v);
318 
319 private:
320 
332  // *NS_CHECK_STYLE_OFF*
333  friend inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs) { return lhs._v == rhs._v; };
334  friend inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs) { return lhs._v < rhs._v; };
335  friend inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs) { return lhs._v > rhs._v; };
336 
337  friend inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
338  {
339  lhs._v += rhs._v;
340  return lhs;
341  };
342  friend inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
343  {
344  lhs._v -= rhs._v;
345  return lhs;
346  };
347  friend inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
348  {
349  lhs.Mul (rhs);
350  return lhs;
351  };
352  friend inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
353  {
354  lhs.Div (rhs);
355  return lhs;
356  };
357  // *NS_CHECK_STYLE_ON*
370  friend inline int64x64_t operator + (const int64x64_t & lhs) { return lhs; };
371  friend inline int64x64_t operator - (const int64x64_t & lhs) { return int64x64_t (-lhs._v); };
372  friend inline int64x64_t operator ! (const int64x64_t & lhs) { return int64x64_t (!lhs._v); };
380  void Mul (const int64x64_t & o);
386  void Div (const int64x64_t & o);
411  static uint128_t Umul (const uint128_t a, const uint128_t b);
419  static uint128_t Udiv (const uint128_t a, const uint128_t b);
429  static uint128_t UmulByInvert (const uint128_t a, const uint128_t b);
430 
432 
433 }; // class int64x64_t
434 
435 
436 
437 } // namespace ns3
438 
439 #endif /* INT64X64_128_H */
High precision numerical type, implementing Q64.64 fixed precision.
Definition: int64x64-128.h:56
friend bool operator==(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:333
static const uint64_t HP_MASK_LO
Mask for fraction part.
Definition: int64x64-128.h:60
friend int64x64_t & operator*=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:347
static const uint128_t HP128_MASK_HI_BIT
uint128_t high bit (sign bit).
Definition: int64x64-128.h:58
int64_t GetInt(void) const
Truncate to an integer.
Definition: int64x64-128.h:268
int64x64_t & operator=(const int64x64_t &o)
Assignment.
Definition: int64x64-128.h:214
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+(const int64x64_t &lhs)
Unary operator.
Definition: int64x64-128.h:370
int64_t Round(void) const
Round to the nearest int.
Definition: int64x64-128.h:283
void Mul(const int64x64_t &o)
Implement *=.
Definition: int64x64-128.cc:64
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:334
friend int64x64_t & operator+=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:337
int64x64_t(const long double value)
Constructor from a floating point.
Definition: int64x64-128.h:114
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:372
int128_t _v
The Q64.64 value.
Definition: int64x64-128.h:431
int64_t GetHigh(void) const
Get the integer portion.
Definition: int64x64-128.h:247
int64x64_t(const int64_t hi, const uint64_t lo)
Construct from explicit high and low values.
Definition: int64x64-128.h:194
void Div(const int64x64_t &o)
Implement /=.
uint64_t GetLow(void) const
Get the fractional portion of this value, unscaled.
Definition: int64x64-128.h:257
int64x64_t(const unsigned long long int v)
Construct from an integral type.
Definition: int64x64-128.h:178
int64x64_t(const unsigned int v)
Construct from an integral type.
Definition: int64x64-128.h:168
int64x64_t(const long int v)
Construct from an integral type.
Definition: int64x64-128.h:158
friend int64x64_t & operator-=(int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:342
int64x64_t(const long long int v)
Construct from an integral type.
Definition: int64x64-128.h:163
int64x64_t(const unsigned long int v)
Construct from an integral type.
Definition: int64x64-128.h:173
int64x64_t(const int128_t v)
Construct from an integral type.
Definition: int64x64-128.h:183
friend bool operator>(const int64x64_t &lhs, const int64x64_t &rhs)
Arithmetic operator.
Definition: int64x64-128.h:335
int64x64_t(const int v)
Construct from an integral type.
Definition: int64x64-128.h:153
double GetDouble(void) const
Get this value as a double.
Definition: int64x64-128.h:231
friend int64x64_t operator-(const int64x64_t &lhs)
Unary operator.
Definition: int64x64-128.h:371
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.
Definition: int64x64-128.h:352
int64x64_t(const double value)
Constructor from a floating point.
Definition: int64x64-128.h:109
int64x64_t(const int64x64_t &o)
Copy constructor.
Definition: int64x64-128.h:205
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:73
__uint128_t uint128_t
Some compilers do not have this defined, so we define it.
Definition: int64x64-128.h:38
__int128_t int128_t
Some compilers do not have this defined, so we define it.
Definition: int64x64-128.h:39
#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.