INET Framework for OMNeT++/OMNEST
inet::Int128 Class Reference

#include <Int128.h>

Public Member Functions

void set (const char *sz)
 
 Int128 ()
 
 Int128 (const Int128 &a)
 
 Int128 (const uint32_t &a)
 
 Int128 (const int32_t &a)
 
 Int128 (const uint64_t &a)
 
 Int128 (const int64_t &a)
 
 Int128 (const float a)
 
 Int128 (const double &a)
 
 Int128 (const long double &a)
 
 Int128 (const char *sz)
 
Int128operator= (const Int128 &other)
 
Int128operator= (const int32_t &a)
 
Int128operator= (const uint32_t &a)
 
Int128operator= (const int64_t &a)
 
Int128operator= (const uint64_t &a)
 
Int128operator= (const char *sz)
 
Int128operator= (const float &a)
 
Int128operator= (const double &a)
 
Int128operator= (const long double &a)
 
bool operator! () const
 
Int128 operator- () const
 
Int128 operator~ () const
 
Int128operator++ ()
 
Int128operator-- ()
 
Int128 operator++ (int)
 
Int128 operator-- (int)
 
Int128operator+= (const Int128 &b)
 
Int128operator*= (const Int128 &b)
 
Int128operator>>= (unsigned int n)
 
Int128operator<<= (unsigned int n)
 
Int128operator|= (const Int128 &b)
 
Int128operator&= (const Int128 &b)
 
Int128operator^= (const Int128 &b)
 
const Int128operator+ () const
 
Int128operator-= (const Int128 &b)
 
Int128operator/= (const Int128 &b)
 
Int128operator%= (const Int128 &b)
 
int toInt () const
 
int64_t toInt64 () const
 
const char * toString (uint32_t radix=10) const
 
float toFloat () const
 
double toDouble () const
 
long double toLongDouble () const
 
Int128 div (const Int128 &, Int128 &) const
 
bool bit (unsigned int n) const
 
void bit (unsigned int n, bool val)
 
 operator double ()
 
 operator int ()
 

Static Public Attributes

static const Int128 INT128_MAX
 
static const Int128 INT128_MIN
 

Private Member Functions

 Int128 (const uint64_t &a, const int64_t &b)
 

Private Attributes

uint64_t lo
 
int64_t hi
 

Friends

bool operator< (const Int128 &, const Int128 &)
 
bool operator== (const Int128 &, const Int128 &)
 
bool operator|| (const Int128 &, const Int128 &)
 
bool operator&& (const Int128 &, const Int128 &)
 

Constructor & Destructor Documentation

◆ Int128() [1/11]

inet::Int128::Int128 ( )
inline
61 {}

Referenced by div(), operator-(), and set().

◆ Int128() [2/11]

inet::Int128::Int128 ( const Int128 a)
inline
62 : lo(a.lo), hi(a.hi) {}

◆ Int128() [3/11]

inet::Int128::Int128 ( const uint32_t &  a)
inline
64 : lo(a), hi(0ll) {}

◆ Int128() [4/11]

inet::Int128::Int128 ( const int32_t &  a)
inline
65  : lo(a), hi(0ll)
66  {
67  if (a < 0) hi = -1ll;
68  }

◆ Int128() [5/11]

inet::Int128::Int128 ( const uint64_t &  a)
inline
70 : lo(a), hi(0ll) {}

◆ Int128() [6/11]

inet::Int128::Int128 ( const int64_t &  a)
inline
71  : lo(a), hi(0ll)
72  {
73  if (a < 0) hi = -1ll;
74  }

◆ Int128() [7/11]

inet::Int128::Int128 ( const float  a)
110  : lo((uint64_t)fmodf(a, 18446744073709551616.0f)),
111  hi((int64_t)(a / 18446744073709551616.0f)) {}

◆ Int128() [8/11]

inet::Int128::Int128 ( const double &  a)
114  : lo((uint64_t)fmod(a, 18446744073709551616.0)),
115  hi((int64_t)(a / 18446744073709551616.0)) {}

◆ Int128() [9/11]

inet::Int128::Int128 ( const long double &  a)
118  : lo((uint64_t)fmodl(a, 18446744073709551616.0l)),
119  hi((int64_t)(a / 18446744073709551616.0l)) {}

◆ Int128() [10/11]

inet::Int128::Int128 ( const char *  sz)
inline
80 { set(sz); }

◆ Int128() [11/11]

inet::Int128::Int128 ( const uint64_t &  a,
const int64_t &  b 
)
inlineprivate
100  : lo(a), hi(b) {}

Member Function Documentation

◆ bit() [1/2]

bool inet::Int128::bit ( unsigned int  n) const
290 {
291  if (n >= 128)
292  return hi < 0;
293 
294  if (n < 64)
295  return lo & (1ull << n);
296  else
297  return hi & (1ull << (n - 64));
298 }

Referenced by div().

◆ bit() [2/2]

void inet::Int128::bit ( unsigned int  n,
bool  val 
)
301 {
302  if (n >= 128)
303  return;
304 
305  if (val) {
306  if (n < 64)
307  lo |= (1ull << n);
308  else
309  hi |= (1ull << (n - 64));
310  }
311  else {
312  if (n < 64)
313  lo &= ~(1ull << n);
314  else
315  hi &= ~(1ull << (n - 64));
316  }
317 }

◆ div()

Int128 inet::Int128::div ( const Int128 divisor,
Int128 remainder 
) const
238 {
239  if (!divisor)
240  return 1u / (unsigned int)divisor.lo;
241  // or RaiseException (EXCEPTION_INT_DIVIDE_BY_ZERO,
242 // EXCEPTION_NONCONTINUABLE, 0, nullptr);
243 
244  Int128 ds = (divisor < 0) ? -divisor : divisor;
245  Int128 dd = (*this < 0) ? -*this : *this;
246 
247  // only remainder
248  if (ds > dd) {
249  remainder = *this;
250  return (Int128)0;
251  }
252 
253  Int128 r = (Int128)0;
254  Int128 q = (Int128)0;
255  // while (dd >= ds) { dd -= ds; q += 1; } // extreme slow version
256 
257  unsigned int b = 127;
258  while (r < ds) {
259  r <<= 1;
260  if (dd.bit(b--))
261  r.lo |= 1;
262  }
263  ++b;
264 
265  while (true)
266  if (r < ds) {
267  if (!(b--))
268  break;
269 
270  r <<= 1;
271  if (dd.bit(b))
272  r.lo |= 1;
273  }
274  else {
275  r -= ds;
276  q.bit(b, true);
277  }
278 
279  // correct
280  if ((divisor < 0) ^ (*this < 0))
281  q = -q;
282  if (*this < 0)
283  r = -r;
284 
285  remainder = r;
286  return q;
287 }

Referenced by toString().

◆ operator double()

inet::Int128::operator double ( )
inline
162 { return toDouble(); }

◆ operator int()

inet::Int128::operator int ( )
inline
163 { return toInt(); }

◆ operator!()

bool inet::Int128::operator! ( ) const
inline
104 { return !(hi || lo); }

◆ operator%=()

Int128& inet::Int128::operator%= ( const Int128 b)
inline
141  {
142  this->div(b, *this);
143  return *this;
144  }

◆ operator&=()

Int128& inet::Int128::operator&= ( const Int128 b)
inline
121 { hi &= b.hi; lo &= b.lo; return *this; }

◆ operator*=()

Int128 & inet::Int128::operator*= ( const Int128 b)
215 {
216  if (!b)
217  return *this = 0u;
218  if (b == 1u)
219  return *this;
220 
221  Int128 a(*this);
222  Int128 t(b);
223 
224  lo = 0ull;
225  hi = 0ll;
226 
227  for (unsigned int i = 0; i < 128; ++i) {
228  if (t.lo & 1)
229  *this += a << i;
230 
231  t >>= 1;
232  }
233 
234  return *this;
235 }

◆ operator+()

const Int128& inet::Int128::operator+ ( ) const
inline
125 { return *this; }

◆ operator++() [1/2]

Int128 & inet::Int128::operator++ ( )
169 {
170  ++lo;
171  if (!lo)
172  ++hi;
173 
174  return *this;
175 }

◆ operator++() [2/2]

Int128 inet::Int128::operator++ ( int  )
187 {
188  Int128 b(*this);
189  ++*this;
190 
191  return b;
192 }

◆ operator+=()

Int128 & inet::Int128::operator+= ( const Int128 b)
203 {
204  uint64_t old_lo = lo;
205 
206  lo += b.lo;
207  hi += b.hi;
208  if (lo < old_lo)
209  ++hi;
210 
211  return *this;
212 }

◆ operator-()

Int128 inet::Int128::operator- ( ) const
161 {
162  if (lo == 0)
163  return Int128(0ull, -hi);
164  else
165  return Int128(-lo, ~hi);
166 }

◆ operator--() [1/2]

Int128 & inet::Int128::operator-- ( )
178 {
179  if (!lo)
180  --hi;
181  --lo;
182 
183  return *this;
184 }

◆ operator--() [2/2]

Int128 inet::Int128::operator-- ( int  )
195 {
196  Int128 b(*this);
197  --*this;
198 
199  return b;
200 }

◆ operator-=()

Int128& inet::Int128::operator-= ( const Int128 b)
inline
129  {
130  return *this += (-b);
131  }

◆ operator/=()

Int128& inet::Int128::operator/= ( const Int128 b)
inline
134  {
135  Int128 dummy;
136  *this = this->div(b, dummy);
137  return *this;
138  }

◆ operator<<=()

Int128 & inet::Int128::operator<<= ( unsigned int  n)
351 {
352  if (n >= 128) {
353  lo = hi = 0;
354  return *this;
355  }
356 
357  if (n >= 64) {
358  hi = lo << (n - 64);
359  lo = 0ull;
360  return *this;
361  }
362 
363  if (n) {
364  // shift high qword
365  hi <<= n;
366 
367  // get higher N bits of low qword
368  uint64_t mask = ~((1ull << (64 - n)) - 1);
369 
370  // and add them to high qword
371  hi |= (lo & mask) >> (64 - n);
372 
373  // and finally shift also low qword
374  lo <<= n;
375  }
376 
377  return *this;
378 }

◆ operator=() [1/9]

Int128& inet::Int128::operator= ( const char *  sz)
inline
92 { set(sz); return *this; }

◆ operator=() [2/9]

Int128 & inet::Int128::operator= ( const double &  a)
141 {
142  lo = ((uint64_t)fmod(a, 18446744073709551616.0));
143  hi = ((int64_t)(a / 18446744073709551616.0));
144  return *this;
145 }

◆ operator=() [3/9]

Int128 & inet::Int128::operator= ( const float &  a)
134 {
135  lo = ((uint64_t)fmodf(a, 18446744073709551616.0f));
136  hi = ((int64_t)(a / 18446744073709551616.0f));
137  return *this;
138 }

◆ operator=() [4/9]

Int128& inet::Int128::operator= ( const Int128 other)
inline
85 { lo = other.lo; hi = other.hi; return *this; }

◆ operator=() [5/9]

Int128& inet::Int128::operator= ( const int32_t &  a)
inline
86 { lo = a; hi = 0; return *this; }

◆ operator=() [6/9]

Int128& inet::Int128::operator= ( const int64_t &  a)
inline
89 { lo = a; hi = 0; return *this; }

◆ operator=() [7/9]

Int128 & inet::Int128::operator= ( const long double &  a)
148 {
149  lo = ((uint64_t)fmodl(a, 18446744073709551616.0l));
150  hi = ((int64_t)(a / 18446744073709551616.0l));
151  return *this;
152 }

◆ operator=() [8/9]

Int128& inet::Int128::operator= ( const uint32_t &  a)
inline
87 { lo = a; hi = 0; return *this; }

◆ operator=() [9/9]

Int128& inet::Int128::operator= ( const uint64_t &  a)
inline
90 { lo = a; hi = 0; return *this; }

◆ operator>>=()

Int128 & inet::Int128::operator>>= ( unsigned int  n)
320 {
321  if (n >= 128) {
322  hi = (hi < 0) ? -1ll : 0ll;
323  lo = hi;
324  return *this;
325  }
326 
327  if (n >= 64) {
328  lo = hi >> (n - 64);
329  hi = (hi < 0) ? -1ll : 0ll;
330  return *this;
331  }
332 
333  if (n) {
334  // shift low qword
335  lo >>= n;
336 
337  // get lower N bits of high qword
338  uint64_t mask = (1ull << n) - 1;
339 
340  // and add them to low qword
341  lo |= (hi & mask) << (64 - n);
342 
343  // and finally shift also high qword
344  hi >>= n;
345  }
346 
347  return *this;
348 }

◆ operator^=()

Int128& inet::Int128::operator^= ( const Int128 b)
inline
122 { hi ^= b.hi; lo ^= b.lo; return *this; }

◆ operator|=()

Int128& inet::Int128::operator|= ( const Int128 b)
inline
120 { hi |= b.hi; lo |= b.lo; return *this; }

◆ operator~()

Int128 inet::Int128::operator~ ( ) const
inline
107 { return Int128(~lo, ~hi); }

◆ set()

void inet::Int128::set ( const char *  sz)
65 {
66  lo = 0u;
67  hi = 0;
68 
69  if (opp_isempty(sz))
70  return;
71 
72  uint32_t radix = 10;
73  uint32_t i = 0;
74  bool minus = false;
75 
76  if (sz[i] == '-') {
77  ++i;
78  minus = true;
79  }
80 
81  if (sz[i] == '0') {
82  radix = 8;
83  ++i;
84  if (sz[i] == 'x') {
85  radix = 16;
86  ++i;
87  }
88  }
89 
90  for (; i < strlen(sz); ++i) {
91  uint32_t n = 0;
92  if (sz[i] >= '0' && sz[i] <= '9' && sz[i] < '0' + (int)radix)
93  n = sz[i] - '0';
94  else if (sz[i] >= 'a' && sz[i] <= 'a' + (int)radix - 10)
95  n = sz[i] - 'a' + 10;
96  else if (sz[i] >= 'A' && sz[i] <= 'A' + (int)radix - 10)
97  n = sz[i] - 'A' + 10;
98  else
99  break;
100 
101  (*this) *= radix;
102  (*this) += n;
103  }
104 
105  if (minus)
106  *this = Int128(0) - *this;
107 }

◆ toDouble()

double inet::Int128::toDouble ( ) const
128 {
129  return (double)hi * 18446744073709551616.0
130  + (double)lo;
131 }

◆ toFloat()

float inet::Int128::toFloat ( ) const
122 {
123  return (float)hi * 18446744073709551616.0f
124  + (float)lo;
125 }

◆ toInt()

int inet::Int128::toInt ( ) const
inline
147 { return (int)lo; }

Referenced by toString().

◆ toInt64()

int64_t inet::Int128::toInt64 ( ) const
inline
148 { return (int64_t)lo; }

◆ toLongDouble()

long double inet::Int128::toLongDouble ( ) const
155 {
156  return (long double)hi * 18446744073709551616.0l
157  + (long double)lo;
158 }

◆ toString()

const char * inet::Int128::toString ( uint32_t  radix = 10) const
38 {
39  if (!*this)
40  return "0";
41  if (radix < 2 || radix > 37)
42  return "(invalid radix)";
43 
44  static char sz[256];
45  memset(sz, 0, 256);
46 
47  Int128 r;
48  Int128 ii = (*this < 0) ? -*this : *this;
49  int i = 255;
50  Int128 aux = radix;
51 
52  while (!!ii && i) {
53  ii = ii.div(aux, r);
54  unsigned int c = r.toInt();
55  sz[--i] = c + ((c > 9) ? 'A' - 10 : '0');
56  }
57 
58  if (*this < 0)
59  sz[--i] = '-';
60 
61  return &sz[i];
62 }

Friends And Related Function Documentation

◆ operator&&

bool operator&& ( const Int128 a,
const Int128 b 
)
friend
182 {
183  return (a.hi || a.lo) && (b.hi || b.lo);
184 }

◆ operator<

bool operator< ( const Int128 ,
const Int128  
)
friend
381 {
382  if (a.hi == b.hi) {
383  if (a.hi < 0)
384  return (int64_t)a.lo < (int64_t)b.lo;
385  else
386  return a.lo < b.lo;
387  }
388  else
389  return a.hi < b.hi;
390 }

◆ operator==

bool operator== ( const Int128 a,
const Int128 b 
)
friend
177 {
178  return a.hi == b.hi && a.lo == b.lo;
179 }

◆ operator||

bool operator|| ( const Int128 a,
const Int128 b 
)
friend
187 {
188  return (a.hi || a.lo) || (b.hi || b.lo);
189 }

Member Data Documentation

◆ hi

◆ INT128_MAX

const Int128 inet::Int128::INT128_MAX
static

◆ INT128_MIN

const Int128 inet::Int128::INT128_MIN
static

◆ lo


The documentation for this class was generated from the following files:
inet::units::constants::c
const value< double, compose< units::m, pow< units::s, -1 > > > c(299792458)
inet::Int128::toInt
int toInt() const
Definition: Int128.h:147
inet::Int128::Int128
Int128()
Definition: Int128.h:61
inet::Int128::set
void set(const char *sz)
Definition: Int128.cc:64
inet::Int128::div
Int128 div(const Int128 &, Int128 &) const
Definition: Int128.cc:237
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::Int128::hi
int64_t hi
Definition: Int128.h:43
inet::Int128::toDouble
double toDouble() const
Definition: Int128.cc:127
inet::Int128::lo
uint64_t lo
Definition: Int128.h:42