A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
int64x64-128.h
1 #include "ns3/core-config.h"
2 #if !defined(INT64X64_128_H) && defined (INT64X64_USE_128) && !defined(PYTHON_SCAN)
3 #define INT64X64_128_H
4 
5 #include "ns3/core-config.h"
6 #include <stdint.h>
7 #include <cmath>
8 
9 #if defined(HAVE___UINT128_T) && !defined(HAVE_UINT128_T)
10 typedef __uint128_t uint128_t;
11 typedef __int128_t int128_t;
12 #endif
13 
14 namespace ns3 {
15 
16 #define HP128_MAX_64 18446744073709551615.0
17 #define HP128_MASK_LO ((((int128_t)1)<<64)-1)
18 
19 class int64x64_t
20 {
21 public:
22  inline int64x64_t ()
23  : _v (0)
24  {}
25  inline int64x64_t (double value)
26  {
27  bool is_negative = value < 0;
28  value = is_negative ? -value : value;
29  double hi = std::floor (value);
30  double lo = (value - hi) * HP128_MAX_64;
31  _v = (int128_t)hi;
32  _v <<= 64;
33  _v += (int128_t)lo;
34  _v = is_negative ? -_v : _v;
35  }
36  inline int64x64_t (int v)
37  : _v (v)
38  {
39  _v <<= 64;
40  }
41  inline int64x64_t (long int v)
42  : _v (v)
43  {
44  _v <<= 64;
45  }
46  inline int64x64_t (long long int v)
47  : _v (v)
48  {
49  _v <<= 64;
50  }
51  inline int64x64_t (unsigned int v)
52  : _v (v)
53  {
54  _v <<= 64;
55  }
56  inline int64x64_t (unsigned long int v)
57  : _v (v)
58  {
59  _v <<= 64;
60  }
61  inline int64x64_t (unsigned long long int v)
62  : _v (v)
63  {
64  _v <<= 64;
65  }
66  explicit inline int64x64_t (int64_t hi, uint64_t lo)
67  {
68  bool is_negative = hi<0;
69  _v = is_negative ? -hi : hi;
70  _v <<= 64;
71  _v += lo;
72  _v = is_negative ? -_v : _v;
73  }
74 
75  inline int64x64_t (const int64x64_t &o)
76  : _v (o._v) {}
77  inline int64x64_t &operator = (const int64x64_t &o)
78  {
79  _v = o._v;
80  return *this;
81  }
82 
83  inline double GetDouble (void) const
84  {
85  bool is_negative = _v < 0;
86  uint128_t value = is_negative ? -_v : _v;
87  uint64_t hi = value >> 64;
88  uint64_t lo = value;
89  double flo = lo;
90  flo /= HP128_MAX_64;
91  double retval = hi;
92  retval += flo;
93  retval = is_negative ? -retval : retval;
94  return retval;
95  }
96  inline int64_t GetHigh (void) const
97  {
98  bool negative = _v < 0;
99  int128_t v = negative ? -_v : _v;
100  v >>= 64;
101  int64_t retval = v;
102  return negative ? -retval : retval;
103  }
104  inline uint64_t GetLow (void) const
105  {
106  bool negative = _v < 0;
107  int128_t v = negative ? -_v : _v;
108  int128_t low = v & HP128_MASK_LO;
109  uint64_t retval = low;
110  return retval;
111  }
112 #undef HP128_MAX_64
113 #undef HP128_MASK_LO
114 
115  void MulByInvert (const int64x64_t &o);
116 
117  static int64x64_t Invert (uint64_t v);
118 
119 private:
120  friend bool operator == (const int64x64_t &lhs, const int64x64_t &rhs);
121  friend bool operator != (const int64x64_t &lhs, const int64x64_t &rhs);
122  friend bool operator <= (const int64x64_t &lhs, const int64x64_t &rhs);
123  friend bool operator >= (const int64x64_t &lhs, const int64x64_t &rhs);
124  friend bool operator < (const int64x64_t &lhs, const int64x64_t &rhs);
125  friend bool operator > (const int64x64_t &lhs, const int64x64_t &rhs);
126  friend int64x64_t &operator += (int64x64_t &lhs, const int64x64_t &rhs);
127  friend int64x64_t &operator -= (int64x64_t &lhs, const int64x64_t &rhs);
128  friend int64x64_t &operator *= (int64x64_t &lhs, const int64x64_t &rhs);
129  friend int64x64_t &operator /= (int64x64_t &lhs, const int64x64_t &rhs);
130  friend int64x64_t operator + (const int64x64_t &lhs, const int64x64_t &rhs);
131  friend int64x64_t operator - (const int64x64_t &lhs, const int64x64_t &rhs);
132  friend int64x64_t operator * (const int64x64_t &lhs, const int64x64_t &rhs);
133  friend int64x64_t operator / (const int64x64_t &lhs, const int64x64_t &rhs);
134  friend int64x64_t operator + (const int64x64_t &lhs);
135  friend int64x64_t operator - (const int64x64_t &lhs);
136  friend int64x64_t operator ! (const int64x64_t &lhs);
137  void Mul (const int64x64_t &o);
138  void Div (const int64x64_t &o);
139  static uint128_t UmulByInvert (uint128_t a, uint128_t b);
140  static uint128_t Umul (uint128_t a, uint128_t b);
141  static uint128_t Divu (uint128_t a, uint128_t b);
142  inline int64x64_t (int128_t v)
143  : _v (v) {}
144 
145  int128_t _v;
146 };
147 
148 inline bool operator == (const int64x64_t &lhs, const int64x64_t &rhs)
149 {
150  return lhs._v == rhs._v;
151 }
152 
153 inline bool operator != (const int64x64_t &lhs, const int64x64_t &rhs)
154 {
155  return lhs._v != rhs._v;
156 }
157 
158 inline bool operator < (const int64x64_t &lhs, const int64x64_t &rhs)
159 {
160  return lhs._v < rhs._v;
161 }
162 inline bool operator <= (const int64x64_t &lhs, const int64x64_t &rhs)
163 {
164  return lhs._v <= rhs._v;
165 }
166 
167 inline bool operator >= (const int64x64_t &lhs, const int64x64_t &rhs)
168 {
169  return lhs._v >= rhs._v;
170 }
171 inline bool operator > (const int64x64_t &lhs, const int64x64_t &rhs)
172 {
173  return lhs._v > rhs._v;
174 }
175 inline int64x64_t &operator += (int64x64_t &lhs, const int64x64_t &rhs)
176 {
177  lhs._v += rhs._v;
178  return lhs;
179 }
180 inline int64x64_t &operator -= (int64x64_t &lhs, const int64x64_t &rhs)
181 {
182  lhs._v -= rhs._v;
183  return lhs;
184 }
185 inline int64x64_t &operator *= (int64x64_t &lhs, const int64x64_t &rhs)
186 {
187  lhs.Mul (rhs);
188  return lhs;
189 }
190 inline int64x64_t &operator /= (int64x64_t &lhs, const int64x64_t &rhs)
191 {
192  lhs.Div (rhs);
193  return lhs;
194 }
195 
196 inline int64x64_t operator + (const int64x64_t &lhs)
197 {
198  return lhs;
199 }
200 
201 inline int64x64_t operator - (const int64x64_t &lhs)
202 {
203  return int64x64_t (-lhs._v);
204 }
205 
206 inline int64x64_t operator ! (const int64x64_t &lhs)
207 {
208  return int64x64_t (!lhs._v);
209 }
210 
211 } // namespace ns3
212 
213 #endif /* INT64X64_128_H */