1 /*
2 This code is based on code from the Geometric Tools library,
3 which is licensed under a boost license.
4 Such usage is permitted by the boost license; for details,
5 please see the boost license below.
6 */
7
8 // Geometric Tools, LLC
9 // Copyright (c) 1998-2014
10 // Distributed under the Boost Software License, Version 1.0.
11 // http://www.boost.org/LICENSE_1_0.txt
12 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
13
14 /*************************************************************************
15 * *
16 * We release our improvements to the wildMagic code under our standard *
17 * Vega FEM license, as follows: *
18 * *
19 * Vega FEM Simulation Library Version 3.1 *
20 * *
21 * "improvements to the wildMagic library" , Copyright (C) 2016 USC *
22 * All rights reserved. *
23 * *
24 * Code author: Yijing Li *
25 * http://www.jernejbarbic.com/code *
26 * *
27 * Funding: National Science Foundation *
28 * *
29 * This library is free software; you can redistribute it and/or *
30 * modify it under the terms of the BSD-style license that is *
31 * included with this library in the file LICENSE.txt *
32 * *
33 * This library is distributed in the hope that it will be useful, *
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file *
36 * LICENSE.TXT for more details. *
37 * *
38 *************************************************************************/
39
40
41 #ifndef INTEGER_H
42 #define INTEGER_H
43 #include <exception>
44 #include <string>
45 #include <cassert>
46 #include <cstring>
47
48 template <int N> class Rational;
49
50 class IntegerException : public std::exception
51 {
52 public:
53 IntegerException(const char * reason);
54 IntegerException(const std::string & reason);
55 virtual ~IntegerException() throw();
56 virtual const char * what() const throw();
57
58 protected:
59 std::string r;
60 };
61
62 // N is the number of 32-bit words you want per Integer.
63 template <int N>
64 class Integer
65 {
66 public:
67
68 // Construction and destruction.
69 Integer (int i = 0);
70 Integer (const Integer& value);
71 ~Integer ();
72
73 // Assignment.
74 Integer& operator= (const Integer& value);
75
76 // Comparison.
77 bool operator== (const Integer& value) const;
78 bool operator!= (const Integer& value) const;
79 bool operator< (const Integer& value) const;
80 bool operator<= (const Integer& value) const;
81 bool operator> (const Integer& value) const;
82 bool operator>= (const Integer& value) const;
83
84 // Arithmetic operations.
85 Integer operator- () const;
86 Integer operator+ (const Integer& value) const;
87 Integer operator- (const Integer& value) const;
88 Integer operator* (const Integer& value) const;
89 Integer operator/ (const Integer& value) const;
90 Integer operator% (const Integer& value) const;
91
92 // Arithmetic updates.
93 Integer& operator+= (const Integer& value);
94 Integer& operator-= (const Integer& value);
95 Integer& operator*= (const Integer& value);
96 Integer& operator/= (const Integer& value);
97
98 // Shift operations.
99 Integer operator<< (int shift) const;
100 Integer operator>> (int shift) const;
101
102 // Shift updates.
103 Integer& operator<<= (int shift);
104 Integer& operator>>= (int shift);
105
106 private:
107
108 typedef IntegerException Exception;
109 // Support for comparisons. The return value of compare is
110 // -1 when value0 < value1,
111 // 0 when value0 == value1,
112 // +1 when value0 > value1.
113 static int compare (const Integer& value0, const Integer& value1);
114 int getSign () const;
115
116 // Support for division and modulo.
117 static bool GetDivMod (const Integer& numer, const Integer& denom,
118 Integer& quotient, Integer& remainder);
119
120 static void divSingle (const Integer& numer, short denom,
121 Integer& quotient, Integer& remainder);
122
123 static void divMultiple (const Integer& numer, const Integer& denom,
124 Integer& quotient, Integer& remainder);
125
126 // Miscellaneous utilities.
127 int getLeadingBlock () const;
128 int getTrailingBlock () const;
129 int getLeadingBit (int i) const; // of buffer[i]
130 int getTrailingBit (int i) const; // of buffer[i]
131 int getLeadingBit () const; // of entire number
132 int getTrailingBit () const; // of entire number
133 void setBit (int i, bool on);
134 bool getBit (int i) const;
135 unsigned int toUnsignedInt (int i) const;
136 void fromUnsignedInt (int i, unsigned int value);
137 unsigned int toUnsignedInt (int lo, int hi) const;
138 int toInt (int i) const;
139
140 enum
141 {
142 INT_SIZE = 2*N,
143 INT_BYTES = INT_SIZE*sizeof(short),
144 INT_LAST = INT_SIZE - 1
145 };
146
147 short buffer[INT_SIZE];
148
149 // Rational needs access to private members of Integer.
150 friend class Rational<N>;
151 };
152
153 template <int N>
154 Integer<N> operator* (int i, const Integer<N>& value);
155
156
157
158
159
160 //----------------------------------------------------------------------------
161 template <int N>
Integer(int i)162 Integer<N>::Integer (int i)
163 {
164 if (i >= 0)
165 {
166 memset(buffer, 0, INT_BYTES);
167 }
168 else
169 {
170 memset(buffer, 0xFF, INT_BYTES);
171 }
172 memcpy(buffer, &i, sizeof(int));
173
174 #ifdef WM5_BIG_ENDIAN
175 short save = buffer[0];
176 buffer[0] = buffer[1];
177 buffer[1] = save;
178 #endif
179 }
180 //----------------------------------------------------------------------------
181 template <int N>
Integer(const Integer & value)182 Integer<N>::Integer (const Integer& value)
183 {
184 memcpy(buffer, value.buffer, INT_BYTES);
185 }
186 //----------------------------------------------------------------------------
187 template <int N>
~Integer()188 Integer<N>::~Integer ()
189 {
190 }
191 //----------------------------------------------------------------------------
192 template <int N>
193 Integer<N>& Integer<N>::operator= (const Integer& value)
194 {
195 memcpy(buffer, value.buffer, INT_BYTES);
196 return *this;
197 }
198 //----------------------------------------------------------------------------
199 template <int N>
getSign()200 int Integer<N>::getSign () const
201 {
202 return (buffer[INT_LAST] & 0x8000) ? -1 : +1;
203 }
204 //----------------------------------------------------------------------------
205 template <int N>
206 bool Integer<N>::operator== (const Integer& value) const
207 {
208 return compare(*this, value) == 0;
209 }
210 //----------------------------------------------------------------------------
211 template <int N>
212 bool Integer<N>::operator!= (const Integer& value) const
213 {
214 return compare(*this, value) != 0;
215 }
216 //----------------------------------------------------------------------------
217 template <int N>
218 bool Integer<N>::operator< (const Integer& value) const
219 {
220 int s0 = getSign();
221 int s1 = value.getSign();
222 if (s0 > 0)
223 {
224 if (s1 > 0)
225 {
226 return compare(*this, value) < 0;
227 }
228 else
229 {
230 return false;
231 }
232 }
233 else
234 {
235 if (s1 > 0)
236 {
237 return true;
238 }
239 else
240 {
241 return compare(*this, value) < 0;
242 }
243 }
244 }
245 //----------------------------------------------------------------------------
246 template <int N>
247 bool Integer<N>::operator<= (const Integer& value) const
248 {
249 int s0 = getSign();
250 int s1 = value.getSign();
251 if (s0 > 0)
252 {
253 if (s1 > 0)
254 {
255 return compare(*this, value) <= 0;
256 }
257 else
258 {
259 return false;
260 }
261 }
262 else
263 {
264 if (s1 > 0)
265 {
266 return true;
267 }
268 else
269 {
270 return compare(*this, value) <= 0;
271 }
272 }
273 }
274 //----------------------------------------------------------------------------
275 template <int N>
276 bool Integer<N>::operator> (const Integer& value) const
277 {
278 int s0 = getSign();
279 int s1 = value.getSign();
280 if (s0 > 0)
281 {
282 if (s1 > 0)
283 {
284 return compare(*this, value) > 0;
285 }
286 else
287 {
288 return true;
289 }
290 }
291 else
292 {
293 if (s1 > 0)
294 {
295 return false;
296 }
297 else
298 {
299 return compare(*this, value) > 0;
300 }
301 }
302 }
303 //----------------------------------------------------------------------------
304 template <int N>
305 bool Integer<N>::operator>= (const Integer& value) const
306 {
307 int s0 = getSign();
308 int s1 = value.getSign();
309 if (s0 > 0)
310 {
311 if (s1 > 0)
312 {
313 return compare(*this, value) >= 0;
314 }
315 else
316 {
317 return true;
318 }
319 }
320 else
321 {
322 if (s1 > 0)
323 {
324 return false;
325 }
326 else
327 {
328 return compare(*this, value) >= 0;
329 }
330 }
331 }
332 //----------------------------------------------------------------------------
333 template <int N>
compare(const Integer<N> & value0,const Integer<N> & value1)334 int Integer<N>::compare (const Integer<N>& value0, const Integer<N>& value1)
335 {
336 for(int i = INT_LAST; i >= 0; --i)
337 {
338 unsigned int uiValue0 = (unsigned int)value0.buffer[i];
339 unsigned int uiValue1 = (unsigned int)value1.buffer[i];
340 if (uiValue0 < uiValue1)
341 {
342 return -1;
343 }
344 else if (uiValue0 > uiValue1)
345 {
346 return +1;
347 }
348 }
349 return 0;
350 }
351 //----------------------------------------------------------------------------
352 template <int N>
353 Integer<N> Integer<N>::operator- () const
354 {
355 Integer result = *this;
356
357 // Negate the bits.
358 int i;
359 for(i = 0; i < INT_SIZE; ++i)
360 {
361 result.buffer[i] = ~result.buffer[i];
362 }
363
364 // Add 1 (place in carry bit and add zero to 'result').
365 unsigned int carry = 1;
366 for(i = 0; i < INT_SIZE; ++i)
367 {
368 unsigned int b1 = result.toUnsignedInt(i);
369 unsigned int sum = b1 + carry;
370 result.fromUnsignedInt(i, sum);
371 carry = (sum & 0x00010000) ? 1 : 0;
372 }
373
374 // Test for overflow.
375 if (result.getSign() == getSign())
376 {
377 if (result != 0) throw Exception("Integer overflow in Integer<N>::operator-");
378 }
379
380 return result;
381 }
382 //----------------------------------------------------------------------------
383 template <int N>
384 Integer<N> Integer<N>::operator+ (const Integer& value) const
385 {
386 Integer result;
387
388 unsigned int carry = 0;
389 for(int i = 0; i < INT_SIZE; ++i)
390 {
391 unsigned int b0 = toUnsignedInt(i);
392 unsigned int b1 = value.toUnsignedInt(i);
393 unsigned int sum = b0 + b1 + carry;
394 result.fromUnsignedInt(i, sum);
395 carry = (sum & 0x00010000) ? 1 : 0;
396 }
397
398 // Test for overflow.
399 if (getSign() == value.getSign())
400 {
401 if (result.getSign() != getSign()) throw Exception("Integer overflow in Integer<N>::operator+");
402 }
403
404 return result;
405 }
406 //----------------------------------------------------------------------------
407 template <int N>
408 Integer<N> Integer<N>::operator- (const Integer& value) const
409 {
410 return *this + (-value);
411 }
412 //----------------------------------------------------------------------------
413 template <int N>
414 Integer<N> Integer<N>::operator* (const Integer& value) const
415 {
416 int s0 = getSign();
417 int s1 = value.getSign();
418 int sProduct = s0*s1;
419 Integer op0 = (s0 > 0 ? *this : -*this);
420 Integer op1 = (s1 > 0 ? value : -value);
421
422 // Product of single-digit number with multiple-digit number.
423 unsigned short product[2*INT_SIZE];
424 unsigned short* pCurrent = product;
425
426 // Product of the two multiple-digit operands.
427 unsigned short result[2*INT_SIZE];
428 unsigned short* rCurrent = result;
429 memset(result,0,2*INT_BYTES);
430
431 for(int i0 = 0, size = 2*INT_SIZE; i0 < INT_SIZE; ++i0, --size)
432 {
433 unsigned int b0 = op0.toUnsignedInt(i0);
434 if (b0 > 0)
435 {
436 unsigned short* pBuffer = pCurrent;
437 unsigned int carry = 0;
438 int i1;
439 for(i1 = 0; i1 < INT_SIZE; ++i1)
440 {
441 unsigned int b1 = op1.toUnsignedInt(i1);
442 unsigned int prod = b0*b1 + carry;
443 *pBuffer++ = (unsigned short)(prod & 0x0000FFFF);
444 carry = (prod & 0xFFFF0000) >> 16;
445 }
446 *pBuffer = (unsigned short)carry;
447
448 unsigned short* rBuffer = rCurrent;
449 pBuffer = pCurrent;
450 carry = 0;
451 unsigned int sum, term0, term1;
452 for(i1 = 0; i1 <= INT_SIZE; ++i1)
453 {
454 term0 = (unsigned int)(*pBuffer++);
455 term1 = (unsigned int)(*rBuffer);
456 sum = term0 + term1 + carry;
457 *rBuffer++ = (unsigned short)(sum & 0x0000FFFF);
458 carry = (sum & 0x00010000) ? 1 : 0;
459 }
460
461 for(/**/; carry > 0 && i1 < size; i1++)
462 {
463 term0 = (unsigned int)(*rBuffer);
464 sum = term0 + carry;
465 *rBuffer++ = (unsigned short)(sum & 0x0000FFFF);
466 carry = (sum & 0x00010000) ? 1 : 0;
467 }
468 }
469
470 pCurrent++;
471 rCurrent++;
472 }
473
474 // Test for overflow. You can test earlier inside the previous loop, but
475 // testing here allows you to get an idea of how much overflow there is.
476 // This information might be useful for an application to decide how large
477 // to choose the integer size.
478 for(int i = 2*INT_SIZE-1; i >= INT_SIZE; --i)
479 {
480 if (result[i] != 0) throw Exception("Integer overflow in Integer<N>::operator*");
481 }
482 if ((result[INT_LAST] & 0x8000) != 0) throw Exception("Integer overflow in Integer<N>::operator*");
483
484 Integer intResult;
485 memcpy(intResult.buffer, result, INT_BYTES);
486 if (sProduct < 0)
487 {
488 intResult = -intResult;
489 }
490
491 return intResult;
492 }
493 //----------------------------------------------------------------------------
494 template <int N>
495 Integer<N> operator* (int i, const Integer<N>& value)
496 {
497 return value*i;
498 }
499 //----------------------------------------------------------------------------
500 template <int N>
501 Integer<N> Integer<N>::operator/ (const Integer& value) const
502 {
503 // TO DO. On division by zero, return INVALID or signed INFINITY?
504 Integer quotient, remainder;
505 return GetDivMod(*this, value, quotient, remainder) ? quotient : 0;
506 }
507 //----------------------------------------------------------------------------
508 template <int N>
509 Integer<N> Integer<N>::operator% (const Integer& value) const
510 {
511 // TO DO. On division by zero, return INVALID or signed INFINITY?
512 Integer quotient, remainder;
513 return GetDivMod(*this, value, quotient, remainder) ? remainder : 0;
514 }
515 //----------------------------------------------------------------------------
516 template <int N>
517 Integer<N>& Integer<N>::operator+= (const Integer& value)
518 {
519 *this = *this + value;
520 return *this;
521 }
522 //----------------------------------------------------------------------------
523 template <int N>
524 Integer<N>& Integer<N>::operator-= (const Integer& value)
525 {
526 *this = *this - value;
527 return *this;
528 }
529 //----------------------------------------------------------------------------
530 template <int N>
531 Integer<N>& Integer<N>::operator*= (const Integer& value)
532 {
533 *this = *this * value;
534 return *this;
535 }
536 //----------------------------------------------------------------------------
537 template <int N>
538 Integer<N>& Integer<N>::operator/= (const Integer& value)
539 {
540 *this = *this / value;
541 return *this;
542 }
543 //----------------------------------------------------------------------------
544 template <int N>
545 Integer<N> Integer<N>::operator<< (int shift) const
546 {
547 if (shift < 0)
548 {
549 return 0;
550 }
551 if (shift == 0)
552 {
553 return *this;
554 }
555
556 // Number of 16-bit blocks to shift.
557 Integer result;
558 int blocks = shift/16;
559 if (blocks > INT_LAST)
560 {
561 return 0;
562 }
563
564 int i;
565 if (blocks > 0)
566 {
567 int j = INT_LAST - blocks;
568 for(i = INT_LAST; j >= 0; --i, --j)
569 {
570 result.buffer[i] = buffer[j];
571 }
572
573 for(/**/; i >= 0; --i)
574 {
575 result.buffer[i] = 0;
576 }
577 }
578
579 // Number of left-over bits to shift.
580 int bits = shift % 16;
581 if (bits > 0)
582 {
583 unsigned int lo, hi, value;
584 int iM1;
585 for(i = INT_LAST, iM1 = i - 1; iM1 >= 0; --i, --iM1)
586 {
587 lo = toUnsignedInt(iM1);
588 hi = toUnsignedInt(i);
589 value = (lo | (hi << 16));
590 value <<= bits;
591 result.fromUnsignedInt(i, ((0xFFFF0000 & value) >> 16));
592 }
593
594 value = toUnsignedInt(0);
595 value <<= bits;
596 result.fromUnsignedInt(0, (0x0000FFFF & value));
597 }
598
599 return result;
600 }
601 //----------------------------------------------------------------------------
602 template <int N>
603 Integer<N> Integer<N>::operator>> (int shift) const
604 {
605 if (shift < 0)
606 {
607 return 0;
608 }
609 if (shift == 0)
610 {
611 return *this;
612 }
613
614 // Number of 16-bit blocks to shift.
615 Integer result;
616 int blocks = shift/16;
617 if (blocks > INT_LAST)
618 {
619 return 0;
620 }
621
622 int i;
623 if (blocks > 0)
624 {
625 int j = blocks;
626 for(i = 0; j <= INT_LAST; ++i, ++j)
627 {
628 result.buffer[i] = buffer[j];
629 }
630
631 if (getSign() > 0)
632 {
633 for(/**/; i <= INT_LAST; ++i)
634 {
635 result.buffer[i] = 0;
636 }
637 }
638 else
639 {
640 for(/**/; i <= INT_LAST; ++i)
641 {
642 result.buffer[i] = (short)(0x0000FFFFu);
643 }
644 }
645 }
646
647 // Number of left-over bits to shift.
648 int bits = shift % 16;
649 if (bits > 0)
650 {
651 unsigned int value;
652 int p1;
653 for(i = 0, p1 = 1; p1 <= INT_LAST; ++i, ++p1)
654 {
655 value = toUnsignedInt(i, p1);
656 value >>= bits;
657 result.fromUnsignedInt(i, value);
658 }
659
660 value = toUnsignedInt(INT_LAST);
661 if (getSign() < 0)
662 {
663 value |= 0xFFFF0000; // sign extension
664 }
665 value >>= bits;
666 result.fromUnsignedInt(INT_LAST, value);
667 }
668
669 return result;
670 }
671 //----------------------------------------------------------------------------
672 template <int N>
673 Integer<N>& Integer<N>::operator<<= (int shift)
674 {
675 if (shift <= 0)
676 {
677 return *this;
678 }
679
680 // Number of 16-bit blocks to shift.
681 int blocks = shift/16;
682 if (blocks > INT_LAST)
683 {
684 return *this;
685 }
686
687 int i;
688 if (blocks > 0)
689 {
690 int j = INT_LAST - blocks;
691 for(i = INT_LAST; j >= 0; --i, --j)
692 {
693 buffer[i] = buffer[j];
694 }
695
696 for(/**/; i >= 0; --i)
697 {
698 buffer[i] = 0;
699 }
700 }
701
702 // Number of left-over bits to shift.
703 int bits = shift % 16;
704 if (bits > 0)
705 {
706 unsigned int value;
707 int m1;
708 for(i = INT_LAST, m1 = i-1; m1 >= 0; i--, m1--)
709 {
710 value = toUnsignedInt(m1, i);
711 value <<= bits;
712 fromUnsignedInt(i, ((0xFFFF0000 & value) >> 16));
713 }
714
715 value = toUnsignedInt(0);
716 value <<= bits;
717 fromUnsignedInt(0, (0x0000FFFF & value));
718 }
719
720 return *this;
721 }
722 //----------------------------------------------------------------------------
723 template <int N>
724 Integer<N>& Integer<N>::operator>>= (int shift)
725 {
726 if (shift <= 0)
727 {
728 return *this;
729 }
730
731 // Number of 16-bit blocks to shift.
732 int blocks = shift/16;
733 if (blocks > INT_LAST)
734 {
735 return *this;
736 }
737
738 int i;
739 if (blocks > 0)
740 {
741 int j = blocks;
742 for(i = 0, j = blocks; j <= INT_LAST; ++i, ++j)
743 {
744 buffer[i] = buffer[j];
745 }
746
747 if (getSign() > 0)
748 {
749 for(/**/; i <= INT_LAST; ++i)
750 {
751 buffer[i] = 0;
752 }
753 }
754 else
755 {
756 for(/**/; i <= INT_LAST; ++i)
757 {
758 buffer[i] = -1;
759 }
760 }
761 }
762
763 // Number of left-over bits to shift.
764 int bits = shift % 16;
765 if (bits > 0)
766 {
767 unsigned int value;
768 int p1;
769 for(i = 0, p1 = 1; p1 <= INT_LAST; ++i, ++p1)
770 {
771 value = toUnsignedInt(i, p1);
772 value >>= bits;
773 fromUnsignedInt(i, value);
774 }
775
776 value = toUnsignedInt(INT_LAST);
777 if (getSign() < 0)
778 {
779 value |= 0xFFFF0000; // sign extension
780 }
781 value >>= bits;
782 fromUnsignedInt(INT_LAST, value);
783 }
784
785 return *this;
786 }
787 //----------------------------------------------------------------------------
788 template <int N>
GetDivMod(const Integer & numer,const Integer & denom,Integer & quotient,Integer & remainder)789 bool Integer<N>::GetDivMod (const Integer& numer, const Integer& denom,
790 Integer& quotient, Integer& remainder)
791 {
792 if (denom == 0)
793 {
794 throw Exception("Division by zero in Integer<N>::GetDivMod");
795 quotient = 0;
796 remainder = 0;
797 return false;
798 }
799
800 if (numer == 0)
801 {
802 quotient = 0;
803 remainder = 0;
804 return true;
805 }
806
807 // Work with the absolute values of the numerator and denominator.
808 int s0 = numer.getSign();
809 int s1 = denom.getSign();
810 Integer absNumer = s0*numer;
811 Integer absDenom = s1*denom;
812
813 int comp = compare(absNumer, absDenom);
814 if (comp < 0)
815 {
816 // numerator < denominator: numerator = 0*denominator + numerator
817 quotient = 0;
818 remainder = numer;
819 return true;
820 }
821
822 if (comp == 0)
823 {
824 // numerator == denominator: numerator = 1*denominator + 0
825 quotient = 1;
826 remainder = 0;
827 return true;
828 }
829
830 // numerator > denominator, do the division to find quotient and remainder
831 if (absDenom > 0x0000FFFF)
832 {
833 divMultiple(absNumer, absDenom, quotient, remainder);
834 }
835 else
836 {
837 divSingle(absNumer, absDenom.buffer[0], quotient, remainder);
838 }
839
840 // Apply the original signs of numerator and denominator.
841 quotient *= s0*s1;
842 remainder *= s0;
843
844 #ifdef _DEBUG
845 Integer test = numer - denom*quotient - remainder;
846 assertion(test == 0, "Invalid result\n");
847 #endif
848 return true;
849 }
850 //----------------------------------------------------------------------------
851 template <int N>
divSingle(const Integer & numer,short denom,Integer & quotient,Integer & remainder)852 void Integer<N>::divSingle (const Integer& numer, short denom,
853 Integer& quotient, Integer& remainder)
854 {
855 // The denominator is a single "digit".
856 unsigned int uiDenom = 0x0000FFFF & (unsigned int)denom;
857
858 // Get the numerator.
859 int nStart = numer.getLeadingBlock();
860 const short* nubuffer = &numer.buffer[nStart];
861 unsigned int digit1 = 0;
862
863 // Get the quotient.
864 short* quoBuffer = "ient.buffer[nStart];
865 quotient = 0;
866 int lastNonZero = -1;
867 for(int i = nStart; i >= 0; --i, --nubuffer, --quoBuffer)
868 {
869 unsigned int digitB = digit1;
870 digit1 = 0x0000FFFF & (unsigned int)(*nubuffer);
871 unsigned int uiNumer = (digitB << 16) | digit1;
872 unsigned int uiQuotient = uiNumer/uiDenom;
873 digit1 = uiNumer - uiQuotient*uiDenom;
874 *quoBuffer = (short)(uiQuotient & 0x0000FFFF);
875 if (lastNonZero == -1 && uiQuotient > 0)
876 {
877 lastNonZero = i;
878 }
879 }
880 if (lastNonZero < 0)
881 throw Exception("Unexpected result in Integer<N>::divSingle");
882
883 // Get the remainder.
884 remainder = 0;
885 if (digit1 & 0xFFFF0000)
886 {
887 memcpy(remainder.buffer, &digit1, 2*sizeof(short));
888 #ifdef WM5_BIG_ENDIAN
889 short save = remainder.buffer[0];
890 remainder.buffer[0] = remainder.buffer[1];
891 remainder.buffer[1] = save;
892 #endif
893 }
894 else
895 {
896 unsigned short tmp = (unsigned short)digit1;
897 memcpy(remainder.buffer, &tmp, sizeof(short));
898 }
899 }
900 //----------------------------------------------------------------------------
901 template <int N>
divMultiple(const Integer & numer,const Integer & denom,Integer & quotient,Integer & remainder)902 void Integer<N>::divMultiple (const Integer& numer,
903 const Integer& denom, Integer& quotient, Integer& remainder)
904 {
905 quotient = 0;
906 remainder = 0;
907
908 // Normalization to allow good estimate of quotient. TO DO: It is
909 // possible that the numerator is large enough that normalization causes
910 // overflow when computing the product adjust*numer; an assertion will
911 // fire in this case. Ideally, the overflow would be allowed and the
912 // digit in the overflow position becomes the first digit of the numerator
913 // in the division algorithm. This will require a mixture of Integer<N>
914 // and Integer<N+1>, though.
915 int dInit = denom.getLeadingBlock();
916 int leadingDigit = denom.toInt(dInit);
917 int adjust = 0x10000/(leadingDigit + 1);
918 Integer adjNum = adjust*numer;
919 Integer adjDen = adjust*denom;
920 if (adjDen.getLeadingBlock() != dInit)
921 throw Exception("Unexpected result in Integer<N>::divMultiple");
922
923 // Get first two "digits" of denominator.
924 unsigned int d1 = adjDen.toUnsignedInt(dInit);
925 unsigned int d2 = adjDen.toUnsignedInt(dInit - 1);
926
927 // Determine the maximum necessary division steps.
928 int nInit = adjNum.getLeadingBlock();
929 if (nInit < dInit)
930 throw Exception("Unexpected result in Integer<N>::divMultiple");
931
932 int qInit;
933 unsigned int rHat;
934 if (nInit != dInit)
935 {
936 qInit = nInit - dInit - 1;
937 rHat = 1;
938 }
939 else
940 {
941 qInit = 0;
942 rHat = 0;
943 }
944
945 for(/**/; qInit >= 0; --qInit)
946 {
947 // Get first three indices of remainder.
948 unsigned int n0, n1, n2;
949 if (rHat > 0)
950 {
951 n0 = adjNum.toUnsignedInt(nInit--);
952 n1 = adjNum.toUnsignedInt(nInit--);
953 n2 = adjNum.toUnsignedInt(nInit);
954 }
955 else
956 {
957 n0 = 0;
958 n1 = adjNum.toUnsignedInt(nInit--);
959 n2 = adjNum.toUnsignedInt(nInit);
960 }
961
962 // Estimate the quotient.
963 unsigned int tmp = (n0 << 16) | n1;
964 unsigned int qHat = (n0 != d1 ? tmp/d1 : 0x0000FFFF);
965 unsigned int prod = qHat*d1;
966 if (tmp < prod)
967 throw Exception("Unexpected result in Integer<N>::divMultiple");
968
969 rHat = tmp - prod;
970 if (d2*qHat > 0x10000*rHat + n2)
971 {
972 qHat--;
973 rHat += d1;
974 if (d2*qHat > 0x10000*rHat + n2)
975 {
976 // If this block is entered, we have exactly the quotient for
977 // the division. The adjustment block of code later cannot
978 // happen.
979 qHat--;
980 rHat += d1;
981 }
982 }
983
984 // Compute the quotient for this step of the division.
985 Integer localQuo;
986 localQuo.fromUnsignedInt(qInit, qHat);
987
988 // Compute the remainder.
989 Integer product = localQuo*adjDen;
990 adjNum -= product;
991 if (adjNum < 0)
992 {
993 qHat--;
994 adjNum += adjDen;
995 if (adjNum < 0)
996 throw Exception("Unexpected result in Integer<N>::divMultiple");
997 // assertion(adjNum >= 0, "Unexpected result\n");
998 }
999
1000 // Set quotient digit.
1001 quotient.fromUnsignedInt(qInit, qHat);
1002
1003 if (adjNum >= adjDen)
1004 {
1005 // Prepare to do another division step.
1006 nInit = adjNum.getLeadingBlock();
1007 }
1008 else
1009 {
1010 // Remainder is smaller than divisor, finished dividing.
1011 break;
1012 }
1013 }
1014
1015 // Unnormalize the remainder.
1016 if (adjNum > 0)
1017 {
1018 short divisor = (short)(adjust & 0x0000FFFF);
1019 Integer shouldBeZero;
1020 divSingle(adjNum, divisor, remainder, shouldBeZero);
1021 }
1022 else
1023 {
1024 remainder = 0;
1025 }
1026 }
1027 //----------------------------------------------------------------------------
1028 template <int N>
getLeadingBlock()1029 int Integer<N>::getLeadingBlock () const
1030 {
1031 for(int i = INT_LAST; i >= 0; --i)
1032 {
1033 if (buffer[i] != 0)
1034 {
1035 return i;
1036 }
1037 }
1038 return -1;
1039 }
1040 //----------------------------------------------------------------------------
1041 template <int N>
getTrailingBlock()1042 int Integer<N>::getTrailingBlock () const
1043 {
1044 for(int i = 0; i <= INT_LAST; ++i)
1045 {
1046 if (buffer[i] != 0)
1047 {
1048 return i;
1049 }
1050 }
1051 return -1;
1052 }
1053 //----------------------------------------------------------------------------
1054 template <int N>
getLeadingBit(int i)1055 int Integer<N>::getLeadingBit (int i) const
1056 {
1057 assert(0 <= i && i <= INT_LAST);
1058 if (i < 0 || i > INT_LAST)
1059 {
1060 return -1;
1061 }
1062
1063 // This is a binary search for the high-order bit of buffer[i]. The
1064 // return value is the index into the bits (0 <= index < 16).
1065 int value = (int)buffer[i];
1066 if ((value & 0xFF00) != 0)
1067 {
1068 if ((value & 0xF000) != 0)
1069 {
1070 if ((value & 0xC000) != 0)
1071 {
1072 if ((value & 0x8000) != 0)
1073 {
1074 return 15;
1075 }
1076 else // (value & 0x4000) != 0
1077 {
1078 return 14;
1079 }
1080 }
1081 else // (value & 0x3000) != 0
1082 {
1083 if ((value & 0x2000) != 0)
1084 {
1085 return 13;
1086 }
1087 else // (value & 0x1000) != 0
1088 {
1089 return 12;
1090 }
1091 }
1092 }
1093 else // (value & 0x0F00) != 0
1094 {
1095 if ((value & 0x0C00) != 0)
1096 {
1097 if ((value & 0x0800) != 0)
1098 {
1099 return 11;
1100 }
1101 else // (value & 0x0400) != 0
1102 {
1103 return 10;
1104 }
1105 }
1106 else // (value & 0x0300) != 0
1107 {
1108 if ((value & 0x0200) != 0)
1109 {
1110 return 9;
1111 }
1112 else // (value & 0x0100) != 0
1113 {
1114 return 8;
1115 }
1116 }
1117 }
1118 }
1119 else // (value & 0x00FF)
1120 {
1121 if ((value & 0x00F0) != 0)
1122 {
1123 if ((value & 0x00C0) != 0)
1124 {
1125 if ((value & 0x0080) != 0)
1126 {
1127 return 7;
1128 }
1129 else // (value & 0x0040) != 0
1130 {
1131 return 6;
1132 }
1133 }
1134 else // (value & 0x0030) != 0
1135 {
1136 if ((value & 0x0020) != 0)
1137 {
1138 return 5;
1139 }
1140 else // (value & 0x0010) != 0
1141 {
1142 return 4;
1143 }
1144 }
1145 }
1146 else // (value & 0x000F) != 0
1147 {
1148 if ((value & 0x000C) != 0)
1149 {
1150 if ((value & 0x0008) != 0)
1151 {
1152 return 3;
1153 }
1154 else // (value & 0x0004) != 0
1155 {
1156 return 2;
1157 }
1158 }
1159 else // (value & 0x0003) != 0
1160 {
1161 if ((value & 0x0002) != 0)
1162 {
1163 return 1;
1164 }
1165 else // (value & 0x0001) != 0
1166 {
1167 return 0;
1168 }
1169 }
1170 }
1171 }
1172 }
1173 //----------------------------------------------------------------------------
1174 template <int N>
getTrailingBit(int i)1175 int Integer<N>::getTrailingBit (int i) const
1176 {
1177 assert(0 <= i && i <= INT_LAST);
1178 if (i < 0 || i > INT_LAST)
1179 {
1180 return -1;
1181 }
1182
1183 // This is a binary search for the low-order bit of buffer[i]. The
1184 // return value is the index into the bits (0 <= index < 16).
1185 int value = (int)buffer[i];
1186 if ((value & 0x00FF) != 0)
1187 {
1188 if ((value & 0x000F) != 0)
1189 {
1190 if ((value & 0x0003) != 0)
1191 {
1192 if ((value & 0x0001) != 0)
1193 {
1194 return 0;
1195 }
1196 else // (value & 0x0002) != 0
1197 {
1198 return 1;
1199 }
1200 }
1201 else // (value & 0x000C) != 0
1202 {
1203 if ((value & 0x0004) != 0)
1204 {
1205 return 2;
1206 }
1207 else // (value & 0x0080) != 0
1208 {
1209 return 3;
1210 }
1211 }
1212 }
1213 else // (value & 0x00F0) != 0
1214 {
1215 if ((value & 0x0030) != 0)
1216 {
1217 if ((value & 0x0010) != 0)
1218 {
1219 return 4;
1220 }
1221 else // (value & 0x0020) != 0
1222 {
1223 return 5;
1224 }
1225 }
1226 else // (value & 0x00C0) != 0
1227 {
1228 if ((value & 0x0040) != 0)
1229 {
1230 return 6;
1231 }
1232 else // (value & 0x0080) != 0
1233 {
1234 return 7;
1235 }
1236 }
1237 }
1238 }
1239 else // (value & 0xFF00)
1240 {
1241 if ((value & 0x0F00) != 0)
1242 {
1243 if ((value & 0x0300) != 0)
1244 {
1245 if ((value & 0x0100) != 0)
1246 {
1247 return 8;
1248 }
1249 else // (value & 0x0200) != 0
1250 {
1251 return 9;
1252 }
1253 }
1254 else // (value & 0x0C00) != 0
1255 {
1256 if ((value & 0x0400) != 0)
1257 {
1258 return 10;
1259 }
1260 else // (value & 0x0800) != 0
1261 {
1262 return 11;
1263 }
1264 }
1265 }
1266 else // (value & 0xF000) != 0
1267 {
1268 if ((value & 0x3000) != 0)
1269 {
1270 if ((value & 0x1000) != 0)
1271 {
1272 return 12;
1273 }
1274 else // (value & 0x2000) != 0
1275 {
1276 return 13;
1277 }
1278 }
1279 else // (value & 0xC000) != 0
1280 {
1281 if ((value & 0x4000) != 0)
1282 {
1283 return 14;
1284 }
1285 else // (value & 0x8000) != 0
1286 {
1287 return 15;
1288 }
1289 }
1290 }
1291 }
1292 }
1293 //----------------------------------------------------------------------------
1294 template <int N>
getLeadingBit()1295 int Integer<N>::getLeadingBit () const
1296 {
1297 int block = getLeadingBlock();
1298 if (block >= 0)
1299 {
1300 int bit = getLeadingBit(block);
1301 if (bit >= 0)
1302 {
1303 return bit + 16*block;
1304 }
1305 }
1306
1307 return -1;
1308 }
1309 //----------------------------------------------------------------------------
1310 template <int N>
getTrailingBit()1311 int Integer<N>::getTrailingBit () const
1312 {
1313 int block = getTrailingBlock();
1314 if (block >= 0)
1315 {
1316 int bit = getTrailingBit(block);
1317 if (bit >= 0)
1318 {
1319 return bit + 16*block;
1320 }
1321 }
1322
1323 return -1;
1324 }
1325 //----------------------------------------------------------------------------
1326 template <int N>
setBit(int i,bool on)1327 void Integer<N>::setBit (int i, bool on)
1328 {
1329 // assert(0 <= i && i <= INT_LAST);
1330 int block = i/16;
1331 int bit = i % 16;
1332 if (on)
1333 {
1334 buffer[block] |= (1 << bit);
1335 }
1336 else
1337 {
1338 buffer[block] &= ~(1 << bit);
1339 }
1340 }
1341 //----------------------------------------------------------------------------
1342 template <int N>
getBit(int i)1343 bool Integer<N>::getBit (int i) const
1344 {
1345 // assert(0 <= i && i <= INT_LAST);
1346 int block = i/16;
1347 int bit = i % 16;
1348 return (buffer[block] & (1 << bit)) != 0;
1349 }
1350 //----------------------------------------------------------------------------
1351 template <int N>
toUnsignedInt(int i)1352 unsigned int Integer<N>::toUnsignedInt (int i) const
1353 {
1354 // assert(0 <= i && i <= INT_LAST);
1355 return 0x0000FFFF & (unsigned int)buffer[i];
1356 }
1357 //----------------------------------------------------------------------------
1358 template <int N>
fromUnsignedInt(int i,unsigned int value)1359 void Integer<N>::fromUnsignedInt (int i, unsigned int value)
1360 {
1361 // assert(0 <= i && i <= INT_LAST);
1362 buffer[i] = (short)(value & 0x0000FFFF);
1363 }
1364 //----------------------------------------------------------------------------
1365 template <int N>
toUnsignedInt(int lo,int hi)1366 unsigned int Integer<N>::toUnsignedInt (int lo, int hi) const
1367 {
1368 unsigned int uiLo = toUnsignedInt(lo);
1369 unsigned int uiHi = toUnsignedInt(hi);
1370 return (uiLo | (uiHi << 16));
1371 }
1372 //----------------------------------------------------------------------------
1373 template <int N>
toInt(int i)1374 int Integer<N>::toInt (int i) const
1375 {
1376 // assert(0 <= i && i <= INT_LAST);
1377 return (int)(0x0000FFFF & (unsigned int)buffer[i]);
1378 }
1379 //----------------------------------------------------------------------------
1380 #endif
1381