Dune Core Modules (2.3.1)

bigunsignedint.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// $Id$
4
5#ifndef DUNE_BIGUNSIGNEDINT_HH
6#define DUNE_BIGUNSIGNEDINT_HH
7
8#include <iostream>
9#include <limits>
10#include <cstdlib>
12#include <dune/common/hash.hh>
13
20namespace Dune
21{
27#if HAVE_MPI
28 template<class K>
29 struct MPITraits;
30#endif
31
41 template<int k>
43 public:
44
45 // unsigned short is 16 bits wide, n is the number of digits needed
46 enum { bits=std::numeric_limits<unsigned short>::digits, n=k/bits+(k%bits!=0),
47 hexdigits=4, bitmask=0xFFFF, compbitmask=0xFFFF0000,
48 overflowmask=0x1 };
49
52
54 bigunsignedint (int x);
55
57 bigunsignedint (std::size_t x);
58
60 void print (std::ostream& s) const ;
61
64
67
70
73
78
83
84
87
90
93
96
97
99 bigunsignedint<k> operator<< (int i) const;
100
102 bigunsignedint<k> operator>> (int i) const;
103
104
106 bool operator< (const bigunsignedint<k>& x) const;
107
109 bool operator<= (const bigunsignedint<k>& x) const;
110
112 bool operator> (const bigunsignedint<k>& x) const;
113
115 bool operator>= (const bigunsignedint<k>& x) const;
116
118 bool operator== (const bigunsignedint<k>& x) const;
119
121 bool operator!= (const bigunsignedint<k>& x) const;
122
123
125 // operator unsigned int () const;
126 unsigned int touint() const;
132 double todouble() const;
133
134 friend class bigunsignedint<k/2>;
135 friend struct std::numeric_limits< bigunsignedint<k> >;
136
137#if HAVE_DUNE_HASH
138
139 inline friend std::size_t hash_value(const bigunsignedint& arg)
140 {
141 return hash_range(arg.digit,arg.digit + arg.n);
142 }
143
144#endif // HAVE_DUNE_HASH
145
146 private:
147 unsigned short digit[n];
148#if HAVE_MPI
149 friend struct MPITraits<bigunsignedint<k> >;
150#endif
151 inline void assign(std::size_t x);
152
153
154 } ;
155
156 // Constructors
157 template<int k>
159 {
160 assign(0u);
161 }
162
163 template<int k>
165 {
166 std::size_t x = std::abs(y);
167 assign(x);
168 }
169
170 template<int k>
172 {
173 assign(x);
174 }
175 template<int k>
176 void bigunsignedint<k>::assign(std::size_t x)
177 {
178 int no=std::min(static_cast<int>(n),
179 static_cast<int>(std::numeric_limits<std::size_t>::digits/bits));
180
181 for(int i=0; i<no; ++i) {
182 digit[i] = (x&bitmask);
183 x=x>>bits;
184 }
185 for (unsigned int i=no; i<n; i++) digit[i]=0;
186 }
187
188 // export
189 template<int k>
190 inline unsigned int bigunsignedint<k>::touint () const
191 {
192 return (digit[1]<<bits)+digit[0];
193 }
194
195 template<int k>
196 inline double bigunsignedint<k>::todouble() const
197 {
198 int firstInZeroRange=n;
199 for(int i=n-1; i>=0; --i)
200 if(digit[i]!=0)
201 break;
202 else
203 --firstInZeroRange;
204 int representableDigits=std::numeric_limits<double>::digits/bits;
205 int lastInRepresentableRange=0;
206 if(representableDigits<firstInZeroRange)
207 lastInRepresentableRange=firstInZeroRange-representableDigits;
208 double val=0;
209 for(int i=firstInZeroRange-1; i>=lastInRepresentableRange; --i)
210 val =val*(1<<bits)+digit[i];
211 return val*(1<<(bits*lastInRepresentableRange));
212 }
213 // print
214 template<int k>
215 inline void bigunsignedint<k>::print (std::ostream& s) const
216 {
217 bool leading=false;
218
219 // print from left to right
220 for (int i=n-1; i>=0; i--)
221 for (int d=hexdigits-1; d>=0; d--)
222 {
223 // extract one hex digit
224 int current = (digit[i]>>(d*4))&0xF;
225 if (current!=0)
226 {
227 // s.setf(std::ios::noshowbase);
228 s << std::hex << current;
229 leading = false;
230 }
231 else if (!leading) s << std::hex << current;
232 }
233 if (leading) s << "0";
234 s << std::dec;
235 }
236
237 template <int k>
238 inline std::ostream& operator<< (std::ostream& s, const bigunsignedint<k>& x)
239 {
240 x.print(s);
241 return s;
242 }
243
244
245 // Operators
246 template <int k>
248 {
249 bigunsignedint<k> result;
250 int overflow=0;
251
252 for (unsigned int i=0; i<n; i++)
253 {
254 int sum = ((int)digit[i]) + ((int)x.digit[i]) + overflow;
255 result.digit[i] = sum&bitmask;
256 overflow = (sum>>bits)&overflowmask;
257 }
258 return result;
259 }
260
261 template <int k>
263 {
264 bigunsignedint<k> result;
265 int overflow=0;
266
267 for (unsigned int i=0; i<n; i++)
268 {
269 int diff = ((int)digit[i]) - (((int)x.digit[i]) + overflow);
270 if (diff>=0)
271 result.digit[i] = (unsigned short) diff;
272 else
273 {
274 result.digit[i] = (unsigned short) (diff+bitmask);
275 overflow = 1;
276 }
277 }
278 return result;
279 }
280
281 template <int k>
283 {
284 bigunsignedint<2*k> finalproduct(0);
285
286 for (unsigned int m=0; m<n; m++) // digit in right factor
287 {
288 bigunsignedint<2*k> singleproduct(0);
289 unsigned int overflow(0);
290 for (unsigned int i=0; i<n; i++)
291 {
292 unsigned int digitproduct = ((unsigned int)digit[i])*((unsigned int)x.digit[m])+overflow;
293 singleproduct.digit[i+m] = (unsigned short) (digitproduct&bitmask);
294 overflow = (digitproduct>>bits)&bitmask;
295 }
296 finalproduct = finalproduct+singleproduct;
297 }
298
299 bigunsignedint<k> result;
300 for (unsigned int i=0; i<n; i++) result.digit[i] = finalproduct.digit[i];
301 return result;
302 }
303
304 template <int k>
306 {
307 int overflow=1;
308
309 for (unsigned int i=0; i<n; i++)
310 {
311 int sum = ((int)digit[i]) + overflow;
312 digit[i] = sum&bitmask;
313 overflow = (sum>>bits)&overflowmask;
314 }
315 return *this;
316 }
317
318 template <int k>
320 {
321 if(x==0)
322 DUNE_THROW(Dune::MathError, "division by zero!");
323
324 // better slow than nothing
325 bigunsignedint<k> temp(*this);
326 bigunsignedint<k> result(0);
327
328 while (temp>=x)
329 {
330 ++result;
331 temp = temp-x;
332 }
333
334 return result;
335 }
336
337 template <int k>
339 {
340 // better slow than nothing
341 bigunsignedint<k> temp(*this);
342 bigunsignedint<k> result(0);
343
344 while (temp>=x)
345 {
346 ++result;
347 temp = temp-x;
348 }
349
350 return temp;
351 }
352
353
354 template <int k>
356 {
357 bigunsignedint<k> result;
358 for (unsigned int i=0; i<n; i++)
359 result.digit[i] = digit[i]&x.digit[i];
360 return result;
361 }
362
363 template <int k>
365 {
366 bigunsignedint<k> result;
367 for (unsigned int i=0; i<n; i++)
368 result.digit[i] = digit[i]^x.digit[i];
369 return result;
370 }
371
372 template <int k>
374 {
375 bigunsignedint<k> result;
376 for (unsigned int i=0; i<n; i++)
377 result.digit[i] = digit[i]|x.digit[i];
378 return result;
379 }
380
381 template <int k>
383 {
384 bigunsignedint<k> result;
385 for (unsigned int i=0; i<n; i++)
386 result.digit[i] = ~digit[i];
387 return result;
388 }
389
390 template <int k>
392 {
393 bigunsignedint<k> result(0);
394
395 // multiples of bits
396 int j=shift/bits;
397 for (int i=n-1-j; i>=0; i--)
398 result.digit[i+j] = digit[i];
399
400 // remainder
401 j=shift%bits;
402 for (int i=n-1; i>=0; i--)
403 {
404 unsigned int temp = result.digit[i];
405 temp = temp<<j;
406 result.digit[i] = (unsigned short) (temp&bitmask);
407 temp = temp>>bits;
408 if (i+1<(int)n)
409 result.digit[i+1] = result.digit[i+1]|temp;
410 }
411
412 return result;
413 }
414
415 template <int k>
417 {
418 bigunsignedint<k> result(0);
419
420 // multiples of bits
421 int j=shift/bits;
422 for (unsigned int i=0; i<n-j; i++)
423 result.digit[i] = digit[i+j];
424
425 // remainder
426 j=shift%bits;
427 for (unsigned int i=0; i<n; i++)
428 {
429 unsigned int temp = result.digit[i];
430 temp = temp<<(bits-j);
431 result.digit[i] = (unsigned short) ((temp&compbitmask)>>bits);
432 if (i>0)
433 result.digit[i-1] = result.digit[i-1] | (temp&bitmask);
434 }
435
436 return result;
437 }
438
439 template <int k>
441 {
442 for (unsigned int i=0; i<n; i++)
443 if (digit[i]!=x.digit[i]) return true;
444 return false;
445 }
446
447 template <int k>
449 {
450 return !((*this)!=x);
451 }
452
453 template <int k>
455 {
456 for (int i=n-1; i>=0; i--)
457 if (digit[i]<x.digit[i]) return true;
458 else if (digit[i]>x.digit[i]) return false;
459 return false;
460 }
461
462 template <int k>
464 {
465 for (int i=n-1; i>=0; i--)
466 if (digit[i]<x.digit[i]) return true;
467 else if (digit[i]>x.digit[i]) return false;
468 return true;
469 }
470
471 template <int k>
473 {
474 return !((*this)<=x);
475 }
476
477 template <int k>
479 {
480 return !((*this)<x);
481 }
482
483
484 template <int k>
485 inline bigunsignedint<k> operator+ (const bigunsignedint<k>& x, std::size_t y)
486 {
487 bigunsignedint<k> temp(y);
488 return x+temp;
489 }
490
491 template <int k>
492 inline bigunsignedint<k> operator- (const bigunsignedint<k>& x, std::size_t y)
493 {
494 bigunsignedint<k> temp(y);
495 return x-temp;
496 }
497
498 template <int k>
499 inline bigunsignedint<k> operator* (const bigunsignedint<k>& x, std::size_t y)
500 {
501 bigunsignedint<k> temp(y);
502 return x*temp;
503 }
504
505 template <int k>
506 inline bigunsignedint<k> operator/ (const bigunsignedint<k>& x, std::size_t y)
507 {
508 bigunsignedint<k> temp(y);
509 return x/temp;
510 }
511
512 template <int k>
513 inline bigunsignedint<k> operator% (const bigunsignedint<k>& x, std::size_t y)
514 {
515 bigunsignedint<k> temp(y);
516 return x%temp;
517 }
518
519 template <int k>
520 inline bigunsignedint<k> operator+ (std::size_t x, const bigunsignedint<k>& y)
521 {
522 bigunsignedint<k> temp(x);
523 return temp+y;
524 }
525
526 template <int k>
527 inline bigunsignedint<k> operator- (std::size_t x, const bigunsignedint<k>& y)
528 {
529 bigunsignedint<k> temp(x);
530 return temp-y;
531 }
532
533 template <int k>
534 inline bigunsignedint<k> operator* (std::size_t x, const bigunsignedint<k>& y)
535 {
536 bigunsignedint<k> temp(x);
537 return temp*y;
538 }
539
540 template <int k>
541 inline bigunsignedint<k> operator/ (std::size_t x, const bigunsignedint<k>& y)
542 {
543 bigunsignedint<k> temp(x);
544 return temp/y;
545 }
546
547 template <int k>
548 inline bigunsignedint<k> operator% (std::size_t x, const bigunsignedint<k>& y)
549 {
550 bigunsignedint<k> temp(x);
551 return temp%y;
552 }
553
554
556}
557
558namespace std
559{
560 template<int k>
561 struct numeric_limits<Dune::bigunsignedint<k> >
562 {
563 public:
564 static const bool is_specialized = true;
565
566 static Dune::bigunsignedint<k> min()
567 {
568 return static_cast<Dune::bigunsignedint<k> >(0);
569 }
570
571 static Dune::bigunsignedint<k> max()
572 {
574 for(std::size_t i=0; i < Dune::bigunsignedint<k>::n; ++i)
575 max_.digit[i]=std::numeric_limits<unsigned short>::max();
576 return max_;
577 }
578
579
580 static const int digits = Dune::bigunsignedint<k>::bits *
582 static const bool is_signed = false;
583 static const bool is_integer = true;
584 static const bool is_exact = true;
585 static const int radix = 2;
586
587 static Dune::bigunsignedint<k> epsilon()
588 {
589 return static_cast<Dune::bigunsignedint<k> >(0);
590 }
591
592 static Dune::bigunsignedint<k> round_error()
593 {
594 return static_cast<Dune::bigunsignedint<k> >(0);
595 }
596
597 static const int min_exponent = 0;
598 static const int min_exponent10 = 0;
599 static const int max_exponent = 0;
600 static const int max_exponent10 = 0;
601
602 static const bool has_infinity = false;
603 static const bool has_quiet_NaN = false;
604 static const bool has_signaling_NaN = false;
605
606 static const float_denorm_style has_denorm = denorm_absent;
607 static const bool has_denorm_loss = false;
608
609 static Dune::bigunsignedint<k> infinity() throw()
610 {
611 return static_cast<Dune::bigunsignedint<k> >(0);
612 }
613
614 static Dune::bigunsignedint<k> quiet_NaN() throw()
615 {
616 return static_cast<Dune::bigunsignedint<k> >(0);
617 }
618
619 static Dune::bigunsignedint<k> signaling_NaN() throw()
620 {
621 return static_cast<Dune::bigunsignedint<k> >(0);
622 }
623
624 static Dune::bigunsignedint<k> denorm_min() throw()
625 {
626 return static_cast<Dune::bigunsignedint<k> >(0);
627 }
628
629 static const bool is_iec559 = false;
630 static const bool is_bounded = true;
631 static const bool is_modulo = true;
632
633 static const bool traps = false;
634 static const bool tinyness_before = false;
635 static const float_round_style round_style = round_toward_zero;
636
637 };
638
639}
640
642
643#endif
Default exception class for mathematical errors.
Definition: exceptions.hh:267
Portable very large unsigned integers.
Definition: bigunsignedint.hh:42
A few common exception classes.
bigunsignedint< k > operator|(const bigunsignedint< k > &x) const
bitwise or
Definition: bigunsignedint.hh:373
bigunsignedint< k > operator<<(int i) const
left shift1/
Definition: bigunsignedint.hh:391
unsigned int touint() const
export to other types
Definition: bigunsignedint.hh:190
bool operator<=(const bigunsignedint< k > &x) const
less than or equal
Definition: bigunsignedint.hh:463
bigunsignedint< k > operator^(const bigunsignedint< k > &x) const
bitwise exor
Definition: bigunsignedint.hh:364
void print(std::ostream &s) const
Print number in hex notation.
Definition: bigunsignedint.hh:215
bigunsignedint< k > operator*(const bigunsignedint< k > &x) const
multiply
Definition: bigunsignedint.hh:282
bool operator<(const bigunsignedint< k > &x) const
less than
Definition: bigunsignedint.hh:454
bool operator==(const bigunsignedint< k > &x) const
equal
Definition: bigunsignedint.hh:448
bool operator!=(const bigunsignedint< k > &x) const
not equal
Definition: bigunsignedint.hh:440
bigunsignedint< k > operator%(const bigunsignedint< k > &x) const
Definition: bigunsignedint.hh:338
bigunsignedint()
Construct uninitialized.
Definition: bigunsignedint.hh:158
bool operator>=(const bigunsignedint< k > &x) const
greater or equal
Definition: bigunsignedint.hh:478
std::ostream & operator<<(std::ostream &s, const array< T, N > &e)
Output operator for array.
Definition: array.hh:159
bigunsignedint< k > operator>>(int i) const
right shift
Definition: bigunsignedint.hh:416
bigunsignedint< k > operator~() const
bitwise komplement
Definition: bigunsignedint.hh:382
bigunsignedint< k > operator-(const bigunsignedint< k > &x) const
subtract
Definition: bigunsignedint.hh:262
bigunsignedint< k > & operator++()
prefix increment
Definition: bigunsignedint.hh:305
double todouble() const
Convert to a double.
Definition: bigunsignedint.hh:196
bigunsignedint< k > operator&(const bigunsignedint< k > &x) const
bitwise and
Definition: bigunsignedint.hh:355
bigunsignedint< k > operator/(const bigunsignedint< k > &x) const
Definition: bigunsignedint.hh:319
bigunsignedint< k > operator+(const bigunsignedint< k > &x) const
add
Definition: bigunsignedint.hh:247
bool operator>(const bigunsignedint< k > &x) const
greater than
Definition: bigunsignedint.hh:472
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
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:126
#define DUNE_HASH_TYPE(...)
Wrapper macro for the type to be hashed in DUNE_DEFINE_HASH.
Definition: hash.hh:143
#define DUNE_HASH_TEMPLATE_ARGS(...)
Wrapper macro for the template arguments in DUNE_DEFINE_HASH.
Definition: hash.hh:135
Dune namespace.
Definition: alignment.hh:14
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:449
STL namespace.
A traits class describing the mapping of types onto MPI_Datatypes.
Definition: mpitraits.hh:37
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)