6#ifndef DUNE_BIGUNSIGNEDINT_HH
7#define DUNE_BIGUNSIGNEDINT_HH
49 struct numeric_limits_helper
54 static std::uint16_t& digit(T& big_unsigned_int, std::size_t i)
56 return big_unsigned_int.digit[i];
77 constexpr static int bits = std::numeric_limits<std::uint16_t>::digits;
78 constexpr static int n = k/bits+(k%bits!=0);
79 constexpr static int hexdigits = 4;
80 constexpr static int bitmask = 0xFFFF;
81 constexpr static int compbitmask = 0xFFFF0000;
82 constexpr static int overflowmask = 0x1;
88 template<
typename Signed>
89 bigunsignedint (Signed x,
typename std::enable_if<std::is_integral<Signed>::value && std::is_signed<Signed>::value>::type* = 0);
95 void print (std::ostream& s)
const ;
168 std::uint_least32_t
touint()
const;
181 return hash_range(arg.digit,arg.digit + arg.n);
185 std::uint16_t digit[n];
189 inline void assign(std::uintmax_t x);
202 template<
typename Signed>
218 static const int no=
std::min(
static_cast<int>(n),
219 static_cast<int>(std::numeric_limits<std::uintmax_t>::digits/bits));
221 for(
int i=0; i<no; ++i) {
222 digit[i] = (x&bitmask);
225 for (
unsigned int i=no; i<n; i++) digit[i]=0;
232 return (digit[1]<<bits)+digit[0];
238 int firstInZeroRange=n;
239 for(
int i=n-1; i>=0; --i)
244 int representableDigits=std::numeric_limits<double>::digits/bits;
245 int lastInRepresentableRange=0;
246 if(representableDigits<firstInZeroRange)
247 lastInRepresentableRange=firstInZeroRange-representableDigits;
249 for(
int i=firstInZeroRange-1; i>=lastInRepresentableRange; --i)
250 val =val*(1<<bits)+digit[i];
251 return val*(1<<(bits*lastInRepresentableRange));
260 for (
int i=n-1; i>=0; i--)
261 for (
int d=hexdigits-1; d>=0; d--)
264 int current = (digit[i]>>(d*4))&0xF;
268 s << std::hex << current;
271 else if (!leading) s << std::hex << current;
273 if (leading) s <<
"0";
284 #define DUNE_BINOP(OP) \
286 inline bigunsignedint<k> bigunsignedint<k>::operator OP (const bigunsignedint<k> &x) const \
305 inline bigunsignedint<k>& bigunsignedint<k>::operator+= (
const bigunsignedint<k>& x)
307 std::uint_fast32_t overflow=0;
309 for (
unsigned int i=0; i<n; i++)
311 std::uint_fast32_t sum =
static_cast<std::uint_fast32_t
>(digit[i]) +
static_cast<std::uint_fast32_t
>(x.digit[i]) + overflow;
312 digit[i] = sum&bitmask;
313 overflow = (sum>>bits)&overflowmask;
319 inline bigunsignedint<k>& bigunsignedint<k>::operator-= (
const bigunsignedint<k>& x)
321 std::int_fast32_t overflow=0;
323 for (
unsigned int i=0; i<n; i++)
325 std::int_fast32_t diff =
static_cast<std::int_fast32_t
>(digit[i]) -
static_cast<std::int_fast32_t
>(x.digit[i]) - overflow;
328 digit[i] =
static_cast<std::uint16_t
>(diff);
333 digit[i] =
static_cast<std::uint16_t
>(diff+bitmask+1);
341 inline bigunsignedint<k>& bigunsignedint<k>::operator*= (
const bigunsignedint<k>& x)
343 bigunsignedint<2*k> finalproduct(0);
345 for (
unsigned int m=0; m<n; m++)
347 bigunsignedint<2*k> singleproduct(0);
348 std::uint_fast32_t overflow(0);
349 for (
unsigned int i=0; i<n; i++)
351 std::uint_fast32_t digitproduct =
static_cast<std::uint_fast32_t
>(digit[i])*
static_cast<std::uint_fast32_t
>(x.digit[m])+overflow;
352 singleproduct.digit[i+m] =
static_cast<std::uint16_t
>(digitproduct&bitmask);
353 overflow = (digitproduct>>bits)&bitmask;
355 finalproduct = finalproduct+singleproduct;
358 for (
unsigned int i=0; i<n; i++) digit[i] = finalproduct.digit[i];
365 std::uint_fast32_t overflow=1;
367 for (
unsigned int i=0; i<n; i++)
369 std::uint_fast32_t sum =
static_cast<std::uint_fast32_t
>(digit[i]) + overflow;
370 digit[i] = sum&bitmask;
371 overflow = (sum>>bits)&overflowmask;
396 inline bigunsignedint<k>& bigunsignedint<k>::operator%= (
const bigunsignedint<k>& x)
408 inline bigunsignedint<k>& bigunsignedint<k>::operator&= (
const bigunsignedint<k>& x)
410 for (
unsigned int i=0; i<n; i++)
411 digit[i] = digit[i]&x.digit[i];
416 inline bigunsignedint<k>& bigunsignedint<k>::operator^= (
const bigunsignedint<k>& x)
418 for (
unsigned int i=0; i<n; i++)
419 digit[i] = digit[i]^x.digit[i];
424 inline bigunsignedint<k>& bigunsignedint<k>::operator|= (
const bigunsignedint<k>& x)
426 for (
unsigned int i=0; i<n; i++)
427 digit[i] = digit[i]|x.digit[i];
435 for (
unsigned int i=0; i<n; i++)
436 result.digit[i] = ~digit[i];
447 for (
int i=n-1-j; i>=0; i--)
448 result.digit[i+j] = digit[i];
452 for (
int i=n-1; i>=0; i--)
454 unsigned int temp = result.digit[i];
456 result.digit[i] =
static_cast<std::uint16_t
>(temp&bitmask);
459 result.digit[i+1] = result.digit[i+1]|temp;
472 for (
unsigned int i=0; i<n-j; i++)
473 result.digit[i] = digit[i+j];
477 for (
unsigned int i=0; i<n; i++)
479 std::uint_fast32_t temp = result.digit[i];
480 temp = temp<<(bits-j);
481 result.digit[i] =
static_cast<std::uint16_t
>((temp&compbitmask)>>bits);
483 result.digit[i-1] = result.digit[i-1] | (temp&bitmask);
492 for (
unsigned int i=0; i<n; i++)
493 if (digit[i]!=x.digit[i])
return true;
500 return !((*this)!=x);
506 for (
int i=n-1; i>=0; i--)
507 if (digit[i]<x.digit[i])
return true;
508 else if (digit[i]>x.digit[i])
return false;
515 for (
int i=n-1; i>=0; i--)
516 if (digit[i]<x.digit[i])
return true;
517 else if (digit[i]>x.digit[i])
return false;
524 return !((*this)<=x);
542 inline bigunsignedint<k> operator- (
const bigunsignedint<k>& x, std::uintmax_t y)
544 bigunsignedint<k> temp(y);
549 inline bigunsignedint<k> operator* (
const bigunsignedint<k>& x, std::uintmax_t y)
551 bigunsignedint<k> temp(y);
556 inline bigunsignedint<k> operator/ (
const bigunsignedint<k>& x, std::uintmax_t y)
558 bigunsignedint<k> temp(y);
563 inline bigunsignedint<k> operator% (
const bigunsignedint<k>& x, std::uintmax_t y)
565 bigunsignedint<k> temp(y);
570 inline bigunsignedint<k> operator+ (std::uintmax_t x,
const bigunsignedint<k>& y)
572 bigunsignedint<k> temp(x);
577 inline bigunsignedint<k> operator- (std::uintmax_t x,
const bigunsignedint<k>& y)
579 bigunsignedint<k> temp(x);
584 inline bigunsignedint<k> operator* (std::uintmax_t x,
const bigunsignedint<k>& y)
586 bigunsignedint<k> temp(x);
591 inline bigunsignedint<k> operator/ (std::uintmax_t x,
const bigunsignedint<k>& y)
593 bigunsignedint<k> temp(x);
598 inline bigunsignedint<k> operator% (std::uintmax_t x,
const bigunsignedint<k>& y)
600 bigunsignedint<k> temp(x);
605 template<
class T>
struct IsNumber;
617 struct numeric_limits<
Dune::bigunsignedint<k> >
618 :
private Dune::Impl::numeric_limits_helper<Dune::bigunsignedint<k> >
621 static const bool is_specialized =
true;
631 for(std::size_t i=0; i < Dune::bigunsignedint<k>::n; ++i)
641 static const bool is_signed =
false;
642 static const bool is_integer =
true;
643 static const bool is_exact =
true;
644 static const int radix = 2;
656 static const int min_exponent = 0;
657 static const int min_exponent10 = 0;
658 static const int max_exponent = 0;
659 static const int max_exponent10 = 0;
661 static const bool has_infinity =
false;
662 static const bool has_quiet_NaN =
false;
663 static const bool has_signaling_NaN =
false;
665 static const float_denorm_style has_denorm = denorm_absent;
666 static const bool has_denorm_loss =
false;
688 static const bool is_iec559 =
false;
689 static const bool is_bounded =
true;
690 static const bool is_modulo =
true;
692 static const bool traps =
false;
693 static const bool tinyness_before =
false;
694 static const float_round_style round_style = round_toward_zero;
Base class for Dune-Exceptions.
Definition: exceptions.hh:96
Default exception class for mathematical errors.
Definition: exceptions.hh:241
Portable very large unsigned integers.
Definition: bigunsignedint.hh:73
bigunsignedint< k > operator|(const bigunsignedint< k > &x) const
bitwise or
bigunsignedint< k > operator^(const bigunsignedint< k > &x) const
bitwise exor
bigunsignedint< k > operator*(const bigunsignedint< k > &x) const
multiply
bigunsignedint< k > operator%(const bigunsignedint< k > &x) const
bigunsignedint< k > operator-(const bigunsignedint< k > &x) const
subtract
bigunsignedint< k > operator&(const bigunsignedint< k > &x) const
bitwise and
bigunsignedint< k > operator/(const bigunsignedint< k > &x) const
bigunsignedint< k > operator+(const bigunsignedint< k > &x) const
add
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:506
bigunsignedint< k > operator<<(int i) const
left shift
Definition: bigunsignedint.hh:441
bool operator<=(const bigunsignedint< k > &x) const
less than or equal
Definition: bigunsignedint.hh:513
void print(std::ostream &s) const
Print number in hex notation.
Definition: bigunsignedint.hh:255
bool operator<(const bigunsignedint< k > &x) const
less than
Definition: bigunsignedint.hh:504
bool operator==(const bigunsignedint< k > &x) const
equal
Definition: bigunsignedint.hh:498
bool operator!=(const bigunsignedint< k > &x) const
not equal
Definition: bigunsignedint.hh:490
bigunsignedint()
Construct uninitialized.
Definition: bigunsignedint.hh:196
bool operator>=(const bigunsignedint< k > &x) const
greater or equal
Definition: bigunsignedint.hh:528
bigunsignedint< k > operator>>(int i) const
right shift
Definition: bigunsignedint.hh:466
bigunsignedint< k > operator~() const
bitwise complement
Definition: bigunsignedint.hh:432
bigunsignedint< k > & operator++()
prefix increment
Definition: bigunsignedint.hh:363
double todouble() const
Convert to a double.
Definition: bigunsignedint.hh:236
bool operator>(const bigunsignedint< k > &x) const
greater than
Definition: bigunsignedint.hh:522
std::uint_least32_t touint() const
export to other types
Definition: bigunsignedint.hh:230
Support for calculating hash values of objects.
#define DUNE_DEFINE_HASH(template_args, type)
Defines the required struct specialization to make type hashable via Dune::hash.
Definition: hash.hh:100
#define DUNE_HASH_TYPE(...)
Wrapper macro for the type to be hashed in DUNE_DEFINE_HASH.
Definition: hash.hh:117
#define DUNE_HASH_TEMPLATE_ARGS(...)
Wrapper macro for the template arguments in DUNE_DEFINE_HASH.
Definition: hash.hh:109
Dune namespace.
Definition: alignedallocator.hh:13
std::size_t hash_range(It first, It last)
Hashes all elements in the range [first,last) and returns the combined hash.
Definition: hash.hh:322
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition: typetraits.hh:194
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: mpitraits.hh:41