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 = &quotient.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