A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
int64x64-cairo.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 #if !defined(INT64X64_CAIRO_H) && defined (INT64X64_USE_CAIRO) && !defined(PYTHON_SCAN)
22 #define INT64X64_CAIRO_H
23 
24 #include <cmath> // pow
25 
26 #include "cairo-wideint-private.h"
27 
34 namespace ns3 {
35 
40 class int64x64_t
41 {
43  static const uint64_t HPCAIRO_MASK_HI_BIT = (((uint64_t)1)<<63);
45  static const uint64_t HP_MASK_LO = 0xffffffffffffffffULL;
58 #define HP_MAX_64 (std::pow (2.0L, 64))
59 
60 public:
68  enum impl_type {
69  int128_impl,
70  cairo_impl,
71  ld_impl,
72  };
73 
75  static const enum impl_type implementation = cairo_impl;
76 
78  inline int64x64_t ()
79  {
80  _v.hi = 0;
81  _v.lo = 0;
82  }
89  inline int64x64_t (const double value)
90  {
91  const int64x64_t tmp ((long double)value);
92  _v = tmp._v;
93  }
94  inline int64x64_t (const long double value)
95  {
96  const bool negative = value < 0;
97  const long double v = negative ? -value : value;
98 
99  long double fhi;
100  long double flo = std::modf (v, &fhi);
101  // Add 0.5 to round, which improves the last count
102  // This breaks these tests:
103  // TestSuite devices-mesh-dot11s-regression
104  // TestSuite devices-mesh-flame-regression
105  // TestSuite routing-aodv-regression
106  // TestSuite routing-olsr-regression
107  // Setting round = 0; breaks:
108  // TestSuite int64x64
109  const long double round = 0.5;
110  flo = flo * HP_MAX_64 + round;
111  cairo_int64_t hi = fhi;
112  const cairo_uint64_t lo = flo;
113  if (flo >= HP_MAX_64)
114  {
115  // conversion to uint64 rolled over
116  ++hi;
117  }
118  _v.hi = hi;
119  _v.lo = lo;
120  _v = negative ? _cairo_int128_negate (_v) : _v;
121  }
130  inline int64x64_t (const int v)
131  {
132  _v.hi = v;
133  _v.lo = 0;
134  }
135  inline int64x64_t (const long int v)
136  {
137  _v.hi = v;
138  _v.lo = 0;
139  }
140  inline int64x64_t (const long long int v)
141  {
142  _v.hi = v;
143  _v.lo = 0;
144  }
145  inline int64x64_t (const unsigned int v)
146  {
147  _v.hi = v;
148  _v.lo = 0;
149  }
150  inline int64x64_t (const unsigned long int v)
151  {
152  _v.hi = v;
153  _v.lo = 0;
154  }
155  inline int64x64_t (const unsigned long long int v)
156  {
157  _v.hi = v;
158  _v.lo = 0;
159  }
167  explicit inline int64x64_t (const int64_t hi, const uint64_t lo)
168  {
169  _v.hi = hi;
170  _v.lo = lo;
171  }
172 
178  inline int64x64_t (const int64x64_t & o)
179  : _v (o._v) {}
185  inline int64x64_t & operator = (const int64x64_t & o)
186  {
187  _v = o._v;
188  return *this;
189  }
190 
196  inline double GetDouble (void) const
197  {
198  const bool negative = _cairo_int128_negative (_v);
199  const cairo_int128_t value = negative ? _cairo_int128_negate (_v) : _v;
200  const long double fhi = value.hi;
201  const long double flo = value.lo / HP_MAX_64;
202  long double retval = fhi;
203  retval += flo;
204  retval = negative ? -retval : retval;
205  return retval;
206  }
212  inline int64_t GetHigh (void) const
213  {
214  return (int64_t)_v.hi;
215  }
221  inline uint64_t GetLow (void) const
222  {
223  return _v.lo;
224  }
225 
234  void MulByInvert (const int64x64_t & o);
235 
249  static int64x64_t Invert (const uint64_t v);
250 
251 private:
252  friend bool operator == (const int64x64_t & lhs, const int64x64_t & rhs);
253 
254  friend bool operator < (const int64x64_t & lhs, const int64x64_t & rhs);
255  friend bool operator > (const int64x64_t & lhs, const int64x64_t & rhs);
256 
257  friend int64x64_t & operator += ( int64x64_t & lhs, const int64x64_t & rhs);
258  friend int64x64_t & operator -= ( int64x64_t & lhs, const int64x64_t & rhs);
259  friend int64x64_t & operator *= ( int64x64_t & lhs, const int64x64_t & rhs);
260  friend int64x64_t & operator /= ( int64x64_t & lhs, const int64x64_t & rhs);
261 
262  friend int64x64_t operator - (const int64x64_t & lhs);
263  friend int64x64_t operator ! (const int64x64_t & lhs);
264 
270  void Mul (const int64x64_t & o);
276  void Div (const int64x64_t & o);
301  static cairo_uint128_t Umul (const cairo_uint128_t a, const cairo_uint128_t b);
309  static cairo_uint128_t Udiv (const cairo_uint128_t a, const cairo_uint128_t b);
319  static cairo_uint128_t UmulByInvert (const cairo_uint128_t a, const cairo_uint128_t b);
320 
321  cairo_int128_t _v;
322 
323 }; // class int64x64_t
324 
325 
330 inline bool operator == (const int64x64_t & lhs, const int64x64_t & rhs)
331 {
332  return _cairo_int128_eq (lhs._v, rhs._v);
333 }
338 inline bool operator < (const int64x64_t & lhs, const int64x64_t & rhs)
339 {
340  return _cairo_int128_lt (lhs._v, rhs._v);
341 }
346 inline bool operator > (const int64x64_t & lhs, const int64x64_t & rhs)
347 {
348  return _cairo_int128_gt (lhs._v, rhs._v);
349 }
350 
355 inline int64x64_t & operator += (int64x64_t & lhs, const int64x64_t & rhs)
356 {
357  lhs._v = _cairo_int128_add( lhs._v, rhs._v );
358  return lhs;
359 }
364 inline int64x64_t & operator -= (int64x64_t & lhs, const int64x64_t & rhs)
365 {
366  lhs._v = _cairo_int128_sub( lhs._v, rhs._v );
367  return lhs;
368 }
373 inline int64x64_t & operator *= (int64x64_t & lhs, const int64x64_t & rhs)
374 {
375  lhs.Mul (rhs);
376  return lhs;
377 }
382 inline int64x64_t & operator /= (int64x64_t & lhs, const int64x64_t & rhs)
383 {
384  lhs.Div (rhs);
385  return lhs;
386 }
387 
392 inline int64x64_t operator + (const int64x64_t & lhs)
393 {
394  return lhs;
395 }
400 inline int64x64_t operator - (const int64x64_t & lhs)
401 {
402  int64x64_t tmp = lhs;
403  tmp._v = _cairo_int128_negate (tmp._v);
404  return tmp;
405 }
410 inline int64x64_t operator ! (const int64x64_t & lhs)
411 {
412  return (lhs == int64x64_t ()) ? int64x64_t (1, 0) : int64x64_t ();
413 }
414 
415 
416 } // namespace ns3
417 
418 #endif /* INT64X64_CAIRO_H */
High precision numerical type, implementing Q64.64 fixed precision.
bool operator>(const Time &lhs, const Time &rhs)
Definition: nstime.h:752
int64_t cairo_int64_t
int I _cairo_int128_lt(cairo_int128_t a, cairo_int128_t b)
Time & operator+=(Time &lhs, const Time &rhs)
Definition: nstime.h:791
TracedValue< T > & operator/=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
Definition: traced-value.h:673
int64x64_t operator+(const int64x64_t &lhs, const int64x64_t &rhs)
Addition operator.
Definition: int64x64.h:86
#define _cairo_int128_eq(a, b)
TracedValue< T > operator!(const TracedValue< T > &lhs)
Unary arithmetic operator for TracedValue.
Definition: traced-value.h:763
int64x64_t operator-(const int64x64_t &lhs, const int64x64_t &rhs)
Subtraction operator.
Definition: int64x64.h:97
Time & operator-=(Time &lhs, const Time &rhs)
Definition: nstime.h:796
#define _cairo_int128_sub(a, b)
#define _cairo_int128_negative(a)
bool operator==(const BleAccessAddress &a, const BleAccessAddress &b)
TracedValue< T > & operator*=(TracedValue< T > &lhs, const U &rhs)
Operator assignment for TracedValue.
Definition: traced-value.h:664
uint64_t cairo_uint64_t
bool operator<(const BleAccessAddress &a, const BleAccessAddress &b)
#define _cairo_int128_gt(a, b)
Declaration of the cairo_x functions which implement high precision arithmetic.
#define _cairo_int128_negate(a)
#define _cairo_int128_add(a, b)