xref: /aoo41x/main/tools/source/generic/bigint.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_tools.hxx"
30 
31 #include <math.h>
32 #include <tools/tools.h>
33 
34 #include <tools/bigint.hxx>
35 #include <tools/string.hxx>
36 #include <tools/debug.hxx>
37 
38 #include <string.h>
39 #include <ctype.h>
40 
41 static const long MY_MAXLONG  = 0x3fffffff;
42 static const long MY_MINLONG  = -MY_MAXLONG;
43 static const long MY_MAXSHORT = 0x00007fff;
44 static const long MY_MINSHORT = -MY_MAXSHORT;
45 
46 /* Die ganzen Algorithmen zur Addition, Subtraktion, Multiplikation und
47  * Division von langen Zahlen stammen aus SEMINUMERICAL ALGORITHMS von
48  * DONALD E. KNUTH aus der Reihe The Art of Computer Programming. Zu finden
49  * sind diese Algorithmen im Kapitel 4.3.1. The Classical Algorithms.
50  */
51 
52 // Muss auf sal_uInt16/INT16/sal_uInt32/sal_Int32 umgestellt werden !!! W.P.
53 
54 // -----------------------------------------------------------------------
55 
56 void BigInt::MakeBigInt( const BigInt& rVal )
57 {
58     if ( rVal.bIsBig )
59     {
60         memcpy( (void*)this, (const void*)&rVal, sizeof( BigInt ) );
61         while ( nLen > 1 && nNum[nLen-1] == 0 )
62             nLen--;
63     }
64     else
65     {
66         long nTmp = rVal.nVal;
67 
68         nVal   = rVal.nVal;
69         bIsBig = sal_True;
70         if ( nTmp < 0 )
71         {
72             bIsNeg = sal_True;
73             nTmp = -nTmp;
74         }
75         else
76             bIsNeg = sal_False;
77 
78         nNum[0] = (sal_uInt16)(nTmp & 0xffffL);
79         nNum[1] = (sal_uInt16)(nTmp >> 16);
80 #ifndef _WIN16
81         if ( nTmp & 0xffff0000L )
82 #else
83         long l = 0xffff0000L;
84         if ( nTmp & l )
85 #endif
86             nLen = 2;
87         else
88             nLen = 1;
89     }
90 }
91 
92 // -----------------------------------------------------------------------
93 
94 void BigInt::Normalize()
95 {
96     if ( bIsBig )
97     {
98         while ( nLen > 1 && nNum[nLen-1] == 0 )
99             nLen--;
100 
101         if ( nLen < 3 )
102         {
103             if ( nLen < 2 )
104                 nVal = nNum[0];
105             else if ( nNum[1] & 0x8000 )
106                 return;
107             else
108                 nVal = ((long)nNum[1] << 16) + nNum[0];
109 
110             bIsBig = sal_False;
111 
112             if ( bIsNeg )
113                 nVal = -nVal;
114         }
115         // else ist nVal undefiniert !!! W.P.
116     }
117     // wozu, nLen ist doch undefiniert ??? W.P.
118     else if ( nVal & 0xFFFF0000L )
119         nLen = 2;
120     else
121         nLen = 1;
122 }
123 
124 // -----------------------------------------------------------------------
125 
126 void BigInt::Mult( const BigInt &rVal, sal_uInt16 nMul )
127 {
128     sal_uInt16 nK = 0;
129     for ( int i = 0; i < rVal.nLen; i++ )
130     {
131         sal_uInt32 nTmp = (sal_uInt32)rVal.nNum[i] * (sal_uInt32)nMul + nK;
132         nK            = (sal_uInt16)(nTmp >> 16);
133         nNum[i] = (sal_uInt16)nTmp;
134     }
135 
136     if ( nK )
137     {
138         nNum[rVal.nLen] = nK;
139         nLen = rVal.nLen + 1;
140     }
141     else
142         nLen = rVal.nLen;
143 
144     bIsBig = sal_True;
145     bIsNeg = rVal.bIsNeg;
146 }
147 
148 // -----------------------------------------------------------------------
149 
150 void BigInt::Div( sal_uInt16 nDiv, sal_uInt16& rRem )
151 {
152     sal_uInt32 nK = 0;
153     for ( int i = nLen - 1; i >= 0; i-- )
154     {
155         sal_uInt32 nTmp = (sal_uInt32)nNum[i] + (nK << 16);
156         nNum[i] = (sal_uInt16)(nTmp / nDiv);
157         nK            = nTmp % nDiv;
158     }
159     rRem = (sal_uInt16)nK;
160 
161     if ( nNum[nLen-1] == 0 )
162         nLen -= 1;
163 }
164 
165 // -----------------------------------------------------------------------
166 
167 sal_Bool BigInt::IsLess( const BigInt& rVal ) const
168 {
169     if ( rVal.nLen < nLen)
170         return sal_True;
171     if ( rVal.nLen > nLen )
172         return sal_False;
173 
174     int i;
175     for ( i = nLen - 1; i > 0 && nNum[i] == rVal.nNum[i]; i-- )
176     {
177     }
178     return rVal.nNum[i] < nNum[i];
179 }
180 
181 // -----------------------------------------------------------------------
182 
183 void BigInt::AddLong( BigInt& rB, BigInt& rErg )
184 {
185     if ( bIsNeg == rB.bIsNeg )
186     {
187         int  i;
188         char len;
189 
190         // wenn die Zahlen unterschiedlich lang sind, sollte zunaechst bei
191         // der kleineren Zahl die fehlenden Ziffern mit 0 initialisert werden
192         if (nLen >= rB.nLen)
193         {
194             len = nLen;
195             for (i = rB.nLen; i < len; i++)
196                 rB.nNum[i] = 0;
197         }
198         else
199         {
200             len = rB.nLen;
201             for (i = nLen; i < len; i++)
202                 nNum[i] = 0;
203         }
204 
205         // Die Ziffern werden von hinten nach vorne addiert
206         long k;
207         long nZ = 0;
208         for (i = 0, k = 0; i < len; i++) {
209             nZ = (long)nNum[i] + (long)rB.nNum[i] + k;
210             if (nZ & 0xff0000L)
211                 k = 1;
212             else
213                 k = 0;
214             rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
215         }
216         // Trat nach der letzten Addition ein Ueberlauf auf, muss dieser
217         // noch ins Ergebis uebernommen werden
218         if (nZ & 0xff0000L) // oder if(k)
219         {
220             rErg.nNum[i] = 1;
221             len++;
222         }
223         // Die Laenge und das Vorzeichen setzen
224         rErg.nLen   = len;
225         rErg.bIsNeg = bIsNeg && rB.bIsNeg;
226         rErg.bIsBig = sal_True;
227     }
228     // Wenn nur einer der beiden Operanten negativ ist, wird aus der
229     // Addition eine Subtaktion
230     else if (bIsNeg)
231     {
232         bIsNeg = sal_False;
233         rB.SubLong(*this, rErg);
234         bIsNeg = sal_True;
235     }
236     else
237     {
238         rB.bIsNeg = sal_False;
239         SubLong(rB, rErg);
240         rB.bIsNeg = sal_True;
241     }
242 }
243 
244 // -----------------------------------------------------------------------
245 
246 void BigInt::SubLong( BigInt& rB, BigInt& rErg )
247 {
248     if ( bIsNeg == rB.bIsNeg )
249     {
250         int  i;
251         char len;
252         long nZ, k;
253 
254         // wenn die Zahlen unterschiedlich lang sind, sollte zunaechst bei
255         // der kleineren Zahl die fehlenden Ziffern mit 0 initialisert werden
256         if (nLen >= rB.nLen)
257         {
258             len = nLen;
259             for (i = rB.nLen; i < len; i++)
260                 rB.nNum[i] = 0;
261         }
262         else
263         {
264             len = rB.nLen;
265             for (i = nLen; i < len; i++)
266                 nNum[i] = 0;
267         }
268 
269         if ( IsLess(rB) )
270         {
271             for (i = 0, k = 0; i < len; i++)
272             {
273                 nZ = (long)nNum[i] - (long)rB.nNum[i] + k;
274                 if (nZ < 0)
275                     k = -1;
276                 else
277                     k = 0;
278                 rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
279             }
280             rErg.bIsNeg = bIsNeg;
281         }
282         else
283         {
284             for (i = 0, k = 0; i < len; i++)
285             {
286                 nZ = (long)rB.nNum[i] - (long)nNum[i] + k;
287                 if (nZ < 0)
288                     k = -1;
289                 else
290                     k = 0;
291                 rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
292             }
293             // wenn a < b, dann Vorzeichen vom Ergebnis umdrehen
294             rErg.bIsNeg = !bIsNeg;
295         }
296         rErg.nLen   = len;
297         rErg.bIsBig = sal_True;
298     }
299     // Wenn nur einer der beiden Operanten negativ ist, wird aus der
300     // Subtaktion eine Addition
301     else if (bIsNeg)
302     {
303         bIsNeg = sal_False;
304         AddLong(rB, rErg);
305         bIsNeg = sal_True;
306         rErg.bIsNeg = sal_True;
307     }
308     else
309     {
310         rB.bIsNeg = sal_False;
311         AddLong(rB, rErg);
312         rB.bIsNeg = sal_True;
313         rErg.bIsNeg = sal_False;
314     }
315 }
316 
317 // -----------------------------------------------------------------------
318 
319 void BigInt::MultLong( const BigInt& rB, BigInt& rErg ) const
320 {
321     int    i, j;
322     sal_uInt32  nZ, k;
323 
324     rErg.bIsNeg = bIsNeg != rB.bIsNeg;
325     rErg.bIsBig = sal_True;
326     rErg.nLen   = nLen + rB.nLen;
327 
328     for (i = 0; i < rErg.nLen; i++)
329         rErg.nNum[i] = 0;
330 
331     for (j = 0; j < rB.nLen; j++)
332     {
333         for (i = 0, k = 0; i < nLen; i++)
334         {
335             nZ = (sal_uInt32)nNum[i] * (sal_uInt32)rB.nNum[j] +
336                  (sal_uInt32)rErg.nNum[i + j] + k;
337             rErg.nNum[i + j] = (sal_uInt16)(nZ & 0xffffUL);
338             k = nZ >> 16;
339         }
340         rErg.nNum[i + j] = (sal_uInt16)k;
341     }
342 }
343 
344 // -----------------------------------------------------------------------
345 
346 void BigInt::DivLong( const BigInt& rB, BigInt& rErg ) const
347 {
348     int    i, j;
349     long   nTmp;
350     sal_uInt16 nK, nQ, nMult;
351     short  nLenB  = rB.nLen;
352     short  nLenB1 = rB.nLen - 1;
353     BigInt aTmpA, aTmpB;
354 
355     nMult = (sal_uInt16)(0x10000L / ((long)rB.nNum[nLenB1] + 1));
356 
357     aTmpA.Mult( *this, nMult );
358     if ( aTmpA.nLen == nLen )
359     {
360         aTmpA.nNum[aTmpA.nLen] = 0;
361         aTmpA.nLen++;
362     }
363 
364     aTmpB.Mult( rB, nMult );
365 
366     for (j = aTmpA.nLen - 1; j >= nLenB; j--)
367     { // Raten des Divisors
368         nTmp = ( (long)aTmpA.nNum[j] << 16 ) + aTmpA.nNum[j - 1];
369         if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
370             nQ = 0xFFFF;
371         else
372             nQ = (sal_uInt16)(((sal_uInt32)nTmp) / aTmpB.nNum[nLenB1]);
373 
374         if ( ((sal_uInt32)aTmpB.nNum[nLenB1 - 1] * nQ) >
375             ((((sal_uInt32)nTmp) - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
376             nQ--;
377         // Und hier faengt das Teilen an
378         nK = 0;
379         nTmp = 0;
380         for (i = 0; i < nLenB; i++)
381         {
382             nTmp = (long)aTmpA.nNum[j - nLenB + i]
383                    - ((long)aTmpB.nNum[i] * nQ)
384                    - nK;
385             aTmpA.nNum[j - nLenB + i] = (sal_uInt16)nTmp;
386             nK = (sal_uInt16) (nTmp >> 16);
387             if ( nK )
388                 nK = (sal_uInt16)(0x10000UL - nK);
389         }
390         unsigned short& rNum( aTmpA.nNum[j - nLenB + i] );
391         rNum = rNum - nK;   // MSVC yields a warning on -= here, so don't use it
392         if (aTmpA.nNum[j - nLenB + i] == 0)
393             rErg.nNum[j - nLenB] = nQ;
394         else
395         {
396             rErg.nNum[j - nLenB] = nQ - 1;
397             nK = 0;
398             for (i = 0; i < nLenB; i++)
399             {
400                 nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
401                 aTmpA.nNum[j - nLenB + i] = (sal_uInt16)(nTmp & 0xFFFFL);
402                 if (nTmp & 0xFFFF0000L)
403                     nK = 1;
404                 else
405                     nK = 0;
406             }
407         }
408     }
409 
410     rErg.bIsNeg = bIsNeg != rB.bIsNeg;
411     rErg.bIsBig = sal_True;
412     rErg.nLen   = nLen - rB.nLen + 1;
413 }
414 
415 // -----------------------------------------------------------------------
416 
417 void BigInt::ModLong( const BigInt& rB, BigInt& rErg ) const
418 {
419     short  i, j;
420     long   nTmp;
421     sal_uInt16 nK, nQ, nMult;
422     short  nLenB  = rB.nLen;
423     short  nLenB1 = rB.nLen - 1;
424     BigInt aTmpA, aTmpB;
425 
426     nMult = (sal_uInt16)(0x10000L / ((long)rB.nNum[nLenB1] + 1));
427 
428     aTmpA.Mult( *this, nMult);
429     if ( aTmpA.nLen == nLen )
430     {
431         aTmpA.nNum[aTmpA.nLen] = 0;
432         aTmpA.nLen++;
433     }
434 
435     aTmpB.Mult( rB, nMult);
436 
437     for (j = aTmpA.nLen - 1; j >= nLenB; j--)
438     { // Raten des Divisors
439         nTmp = ( (long)aTmpA.nNum[j] << 16 ) + aTmpA.nNum[j - 1];
440         if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
441             nQ = 0xFFFF;
442         else
443             nQ = (sal_uInt16)(((sal_uInt32)nTmp) / aTmpB.nNum[nLenB1]);
444 
445         if ( ((sal_uInt32)aTmpB.nNum[nLenB1 - 1] * nQ) >
446             ((((sal_uInt32)nTmp) - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
447             nQ--;
448         // Und hier faengt das Teilen an
449         nK = 0;
450         nTmp = 0;
451         for (i = 0; i < nLenB; i++)
452         {
453             nTmp = (long)aTmpA.nNum[j - nLenB + i]
454                    - ((long)aTmpB.nNum[i] * nQ)
455                    - nK;
456             aTmpA.nNum[j - nLenB + i] = (sal_uInt16)nTmp;
457             nK = (sal_uInt16) (nTmp >> 16);
458             if ( nK )
459                 nK = (sal_uInt16)(0x10000UL - nK);
460         }
461         unsigned short& rNum( aTmpA.nNum[j - nLenB + i] );
462         rNum = rNum - nK;
463         if (aTmpA.nNum[j - nLenB + i] == 0)
464             rErg.nNum[j - nLenB] = nQ;
465         else
466         {
467             rErg.nNum[j - nLenB] = nQ - 1;
468             nK = 0;
469             for (i = 0; i < nLenB; i++) {
470                 nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
471                 aTmpA.nNum[j - nLenB + i] = (sal_uInt16)(nTmp & 0xFFFFL);
472                 if (nTmp & 0xFFFF0000L)
473                     nK = 1;
474                 else
475                     nK = 0;
476             }
477         }
478     }
479 
480     rErg = aTmpA;
481     rErg.Div( nMult, nQ );
482 }
483 
484 // -----------------------------------------------------------------------
485 
486 sal_Bool BigInt::ABS_IsLess( const BigInt& rB ) const
487 {
488     if (bIsBig || rB.bIsBig)
489     {
490         BigInt nA, nB;
491         nA.MakeBigInt( *this );
492         nB.MakeBigInt( rB );
493         if (nA.nLen == nB.nLen)
494         {
495             int i;
496             for (i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i--)
497             {
498             }
499             return nA.nNum[i] < nB.nNum[i];
500         }
501         else
502             return nA.nLen < nB.nLen;
503     }
504     if ( nVal < 0 )
505         if ( rB.nVal < 0 )
506             return nVal > rB.nVal;
507         else
508             return nVal > -rB.nVal;
509     else
510         if ( rB.nVal < 0 )
511             return nVal < -rB.nVal;
512         else
513             return nVal < rB.nVal;
514 }
515 
516 // -----------------------------------------------------------------------
517 
518 BigInt::BigInt( const BigInt& rBigInt )
519 {
520     if ( rBigInt.bIsBig )
521         memcpy( (void*)this, (const void*)&rBigInt, sizeof( BigInt ) );
522     else
523     {
524         bIsSet = rBigInt.bIsSet;
525         bIsBig = sal_False;
526         nVal   = rBigInt.nVal;
527     }
528 }
529 
530 // -----------------------------------------------------------------------
531 
532 BigInt::BigInt( const ByteString& rString )
533 {
534     bIsSet = sal_True;
535     bIsNeg = sal_False;
536     bIsBig = sal_False;
537     nVal   = 0;
538 
539     sal_Bool bNeg = sal_False;
540     const sal_Char* p = rString.GetBuffer();
541     if ( *p == '-' )
542     {
543         bNeg = sal_True;
544         p++;
545     }
546     while( *p >= '0' && *p <= '9' )
547     {
548         *this *= 10;
549         *this += *p - '0';
550         p++;
551     }
552     if ( bIsBig )
553         bIsNeg = bNeg;
554     else if( bNeg )
555         nVal = -nVal;
556 }
557 
558 // -----------------------------------------------------------------------
559 
560 BigInt::BigInt( const UniString& rString )
561 {
562     bIsSet = sal_True;
563     bIsNeg = sal_False;
564     bIsBig = sal_False;
565     nVal   = 0;
566 
567     sal_Bool bNeg = sal_False;
568     const sal_Unicode* p = rString.GetBuffer();
569     if ( *p == '-' )
570     {
571         bNeg = sal_True;
572         p++;
573     }
574     while( *p >= '0' && *p <= '9' )
575     {
576         *this *= 10;
577         *this += *p - '0';
578         p++;
579     }
580     if ( bIsBig )
581         bIsNeg = bNeg;
582     else if( bNeg )
583         nVal = -nVal;
584 }
585 
586 // -----------------------------------------------------------------------
587 
588 BigInt::BigInt( double nValue )
589 {
590     bIsSet = sal_True;
591 
592     if ( nValue < 0 )
593     {
594         nValue *= -1;
595         bIsNeg  = sal_True;
596     }
597     else
598     {
599         bIsNeg  = sal_False;
600     }
601 
602     if ( nValue < 1 )
603     {
604         bIsBig = sal_False;
605         nVal   = 0;
606     }
607     else
608     {
609         bIsBig = sal_True;
610 
611         int i=0;
612 
613         while ( ( nValue > 65536.0 ) && ( i < MAX_DIGITS ) )
614         {
615             nNum[i] = (sal_uInt16) fmod( nValue, 65536.0 );
616             nValue -= nNum[i];
617             nValue /= 65536.0;
618             i++;
619         }
620         if ( i < MAX_DIGITS )
621             nNum[i++] = (sal_uInt16) nValue;
622 
623         nLen = i;
624 
625         if ( i < 3 )
626             Normalize();
627     }
628 }
629 
630 // -----------------------------------------------------------------------
631 
632 BigInt::BigInt( sal_uInt32 nValue )
633 {
634     bIsSet  = sal_True;
635     if ( nValue & 0x80000000UL )
636     {
637         bIsBig  = sal_True;
638         bIsNeg  = sal_False;
639         nNum[0] = (sal_uInt16)(nValue & 0xffffUL);
640         nNum[1] = (sal_uInt16)(nValue >> 16);
641         nLen    = 2;
642     }
643     else
644     {
645         bIsBig = sal_False;
646         nVal   = nValue;
647     }
648 }
649 
650 // -----------------------------------------------------------------------
651 
652 BigInt::operator sal_uIntPtr() const
653 {
654     if ( !bIsBig )
655         return (sal_uInt32)nVal;
656     else if ( nLen == 2 )
657     {
658         sal_uInt32 nRet;
659         nRet  = ((sal_uInt32)nNum[1]) << 16;
660         nRet += nNum[0];
661         return nRet;
662     }
663     return 0;
664 }
665 
666 // -----------------------------------------------------------------------
667 
668 BigInt::operator double() const
669 {
670     if ( !bIsBig )
671         return (double) nVal;
672     else
673     {
674         int     i = nLen-1;
675         double  nRet = (double) ((sal_uInt32)nNum[i]);
676 
677         while ( i )
678         {
679             nRet *= 65536.0;
680             i--;
681             nRet += (double) ((sal_uInt32)nNum[i]);
682         }
683 
684         if ( bIsNeg )
685             nRet *= -1;
686 
687         return nRet;
688     }
689 }
690 
691 // -----------------------------------------------------------------------
692 
693 ByteString BigInt::GetByteString() const
694 {
695     ByteString aString;
696 
697     if ( !bIsBig )
698         aString = ByteString::CreateFromInt32( nVal );
699     else
700     {
701         BigInt aTmp( *this );
702         BigInt a1000000000( 1000000000L );
703         aTmp.Abs();
704 
705         do
706         {
707             BigInt a = aTmp;
708             a    %= a1000000000;
709             aTmp /= a1000000000;
710 
711             ByteString aStr = aString;
712             if ( a.nVal < 100000000L )
713             { // leading 0s
714                 aString = ByteString::CreateFromInt32( a.nVal + 1000000000L );
715                 aString.Erase( 0, 1 );
716             }
717             else
718                 aString = ByteString::CreateFromInt32( a.nVal );
719             aString += aStr;
720         }
721         while( aTmp.bIsBig );
722 
723         ByteString aStr = aString;
724         if ( bIsNeg )
725             aString = ByteString::CreateFromInt32( -aTmp.nVal );
726         else
727             aString = ByteString::CreateFromInt32( aTmp.nVal );
728         aString += aStr;
729     }
730 
731     return aString;
732 }
733 
734 // -----------------------------------------------------------------------
735 
736 UniString BigInt::GetString() const
737 {
738     UniString aString;
739 
740     if ( !bIsBig )
741         aString = UniString::CreateFromInt32( nVal );
742     else
743     {
744         BigInt aTmp( *this );
745         BigInt a1000000000( 1000000000L );
746         aTmp.Abs();
747 
748         do
749         {
750             BigInt a = aTmp;
751             a    %= a1000000000;
752             aTmp /= a1000000000;
753 
754             UniString aStr = aString;
755             if ( a.nVal < 100000000L )
756             { // leading 0s
757                 aString = UniString::CreateFromInt32( a.nVal + 1000000000L );
758                 aString.Erase(0,1);
759             }
760             else
761                 aString = UniString::CreateFromInt32( a.nVal );
762             aString += aStr;
763         }
764         while( aTmp.bIsBig );
765 
766         UniString aStr = aString;
767         if ( bIsNeg )
768             aString = UniString::CreateFromInt32( -aTmp.nVal );
769         else
770             aString = UniString::CreateFromInt32( aTmp.nVal );
771         aString += aStr;
772     }
773 
774     return aString;
775 }
776 
777 // -----------------------------------------------------------------------
778 
779 BigInt& BigInt::operator=( const BigInt& rBigInt )
780 {
781     if ( rBigInt.bIsBig )
782         memcpy( (void*)this, (const void*)&rBigInt, sizeof( BigInt ) );
783     else
784     {
785         bIsSet = rBigInt.bIsSet;
786         bIsBig = sal_False;
787         nVal   = rBigInt.nVal;
788     }
789     return *this;
790 }
791 
792 // -----------------------------------------------------------------------
793 
794 BigInt& BigInt::operator+=( const BigInt& rVal )
795 {
796     if ( !bIsBig && !rVal.bIsBig )
797     {
798         if( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG
799             && nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
800         { // wir bewegen uns im ungefaehrlichem Bereich
801             nVal += rVal.nVal;
802             return *this;
803         }
804 
805         if( (nVal < 0) != (rVal.nVal < 0) )
806         { // wir bewegen uns im ungefaehrlichem Bereich
807             nVal += rVal.nVal;
808             return *this;
809         }
810     }
811 
812     BigInt aTmp1, aTmp2;
813     aTmp1.MakeBigInt( *this );
814     aTmp2.MakeBigInt( rVal );
815     aTmp1.AddLong( aTmp2, *this );
816     Normalize();
817     return *this;
818 }
819 
820 // -----------------------------------------------------------------------
821 
822 BigInt& BigInt::operator-=( const BigInt& rVal )
823 {
824     if ( !bIsBig && !rVal.bIsBig )
825     {
826         if ( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG &&
827              nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
828         { // wir bewegen uns im ungefaehrlichem Bereich
829             nVal -= rVal.nVal;
830             return *this;
831         }
832 
833         if ( (nVal < 0) == (rVal.nVal < 0) )
834         { // wir bewegen uns im ungefaehrlichem Bereich
835             nVal -= rVal.nVal;
836             return *this;
837         }
838     }
839 
840     BigInt aTmp1, aTmp2;
841     aTmp1.MakeBigInt( *this );
842     aTmp2.MakeBigInt( rVal );
843     aTmp1.SubLong( aTmp2, *this );
844     Normalize();
845     return *this;
846 }
847 
848 // -----------------------------------------------------------------------
849 
850 BigInt& BigInt::operator*=( const BigInt& rVal )
851 {
852     if ( !bIsBig && !rVal.bIsBig
853          && nVal <= MY_MAXSHORT && rVal.nVal <= MY_MAXSHORT
854          && nVal >= MY_MINSHORT && rVal.nVal >= MY_MINSHORT )
855          // nicht optimal !!! W.P.
856     { // wir bewegen uns im ungefaehrlichem Bereich
857         nVal *= rVal.nVal;
858     }
859     else
860     {
861         BigInt aTmp1, aTmp2;
862         aTmp1.MakeBigInt( rVal );
863         aTmp2.MakeBigInt( *this );
864         aTmp1.MultLong(aTmp2, *this);
865         Normalize();
866     }
867     return *this;
868 }
869 
870 // -----------------------------------------------------------------------
871 
872 BigInt& BigInt::operator/=( const BigInt& rVal )
873 {
874     if ( !rVal.bIsBig )
875     {
876         if ( rVal.nVal == 0 )
877         {
878             DBG_ERROR( "BigInt::operator/ --> divide by zero" );
879             return *this;
880         }
881 
882         if ( !bIsBig )
883         {
884             // wir bewegen uns im ungefaehrlichem Bereich
885             nVal /= rVal.nVal;
886             return *this;
887         }
888 
889         if ( rVal.nVal == 1 )
890             return *this;
891 
892         if ( rVal.nVal == -1 )
893         {
894             bIsNeg = !bIsNeg;
895             return *this;
896         }
897 
898         if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
899         {
900             // ein BigInt durch ein sal_uInt16 teilen
901             sal_uInt16 nTmp;
902             if ( rVal.nVal < 0 )
903             {
904                 nTmp = (sal_uInt16) -rVal.nVal;
905                 bIsNeg = !bIsNeg;
906             }
907             else
908                 nTmp = (sal_uInt16) rVal.nVal;
909 
910             Div( nTmp, nTmp );
911             Normalize();
912             return *this;
913         }
914     }
915 
916     if ( ABS_IsLess( rVal ) )
917     {
918         *this = BigInt( (long)0 );
919         return *this;
920     }
921 
922     // BigInt durch BigInt teilen
923     BigInt aTmp1, aTmp2;
924     aTmp1.MakeBigInt( *this );
925     aTmp2.MakeBigInt( rVal );
926     aTmp1.DivLong(aTmp2, *this);
927     Normalize();
928     return *this;
929 }
930 
931 // -----------------------------------------------------------------------
932 
933 void BigInt::DivMod( const BigInt& rVal, BigInt& rMod )
934 {
935     if ( !rVal.bIsBig )
936     {
937         if ( rVal.nVal == 0 )
938         {
939             DBG_ERROR( "BigInt::operator/ --> divide by zero" );
940             return;
941         }
942 
943         if ( !bIsBig )
944         {
945             // wir bewegen uns im ungefaehrlichem Bereich
946             rMod  = BigInt( nVal % rVal.nVal );
947             nVal /= rVal.nVal;
948             return;
949         }
950 
951         if ( rVal.nVal == 1 )
952         {
953             rMod = BigInt( (long)0 );
954             return;
955         }
956 
957         if ( rVal.nVal == -1 )
958         {
959             rMod = BigInt( (long)0 );
960             bIsNeg = !bIsNeg;
961             return;
962         }
963 
964         if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
965         {
966             // ein BigInt durch ein sal_uInt16 teilen
967             sal_uInt16 nTmp;
968             if ( rVal.nVal < 0 )
969             {
970                 nTmp = (sal_uInt16) -rVal.nVal;
971                 bIsNeg = !bIsNeg;
972             }
973             else
974                 nTmp = (sal_uInt16) rVal.nVal;
975 
976             Div( nTmp, nTmp );
977             rMod = BigInt( (long)nTmp );
978             Normalize();
979             return;
980         }
981     }
982 
983     if ( ABS_IsLess( rVal ) )
984     {
985         rMod  = *this;
986         *this = BigInt( (long)0 );
987         return;
988     }
989 
990     // BigInt durch BigInt teilen
991     BigInt aTmp1, aTmp2;
992     aTmp1.MakeBigInt( *this );
993     aTmp2.MakeBigInt( rVal );
994     aTmp1.DivLong(aTmp2, *this);
995     Normalize();
996     aTmp1.ModLong(aTmp2, rMod); // nicht optimal
997     rMod.Normalize();
998 }
999 
1000 // -----------------------------------------------------------------------
1001 
1002 BigInt& BigInt::operator%=( const BigInt& rVal )
1003 {
1004     if ( !rVal.bIsBig )
1005     {
1006         if ( rVal.nVal == 0 )
1007         {
1008             DBG_ERROR( "BigInt::operator/ --> divide by zero" );
1009             return *this;
1010         }
1011 
1012         if ( !bIsBig )
1013         {
1014             // wir bewegen uns im ungefaehrlichem Bereich
1015             nVal %= rVal.nVal;
1016             return *this;
1017         }
1018 
1019         if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
1020         {
1021             // ein BigInt durch ein short teilen
1022             sal_uInt16 nTmp;
1023             if ( rVal.nVal < 0 )
1024             {
1025                 nTmp = (sal_uInt16) -rVal.nVal;
1026                 bIsNeg = !bIsNeg;
1027             }
1028             else
1029                 nTmp = (sal_uInt16) rVal.nVal;
1030 
1031             Div( nTmp, nTmp );
1032             *this = BigInt( (long)nTmp );
1033             return *this;
1034         }
1035     }
1036 
1037     if ( ABS_IsLess( rVal ) )
1038         return *this;
1039 
1040     // BigInt durch BigInt teilen
1041     BigInt aTmp1, aTmp2;
1042     aTmp1.MakeBigInt( *this );
1043     aTmp2.MakeBigInt( rVal );
1044     aTmp1.ModLong(aTmp2, *this);
1045     Normalize();
1046     return *this;
1047 }
1048 
1049 // -----------------------------------------------------------------------
1050 
1051 sal_Bool operator==( const BigInt& rVal1, const BigInt& rVal2 )
1052 {
1053     if ( rVal1.bIsBig || rVal2.bIsBig )
1054     {
1055         BigInt nA, nB;
1056         nA.MakeBigInt( rVal1 );
1057         nB.MakeBigInt( rVal2 );
1058         if ( nA.bIsNeg == nB.bIsNeg )
1059         {
1060             if ( nA.nLen == nB.nLen )
1061             {
1062                 int i;
1063                 for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
1064                 {
1065                 }
1066 
1067                 return nA.nNum[i] == nB.nNum[i];
1068             }
1069             return sal_False;
1070         }
1071         return sal_False;
1072     }
1073     return rVal1.nVal == rVal2.nVal;
1074 }
1075 
1076 // -----------------------------------------------------------------------
1077 
1078 sal_Bool operator<( const BigInt& rVal1, const BigInt& rVal2 )
1079 {
1080     if ( rVal1.bIsBig || rVal2.bIsBig )
1081     {
1082         BigInt nA, nB;
1083         nA.MakeBigInt( rVal1 );
1084         nB.MakeBigInt( rVal2 );
1085         if ( nA.bIsNeg == nB.bIsNeg )
1086         {
1087             if ( nA.nLen == nB.nLen )
1088             {
1089                 int i;
1090                 for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
1091                 {
1092                 }
1093 
1094                 if ( nA.bIsNeg )
1095                     return nA.nNum[i] > nB.nNum[i];
1096                 else
1097                     return nA.nNum[i] < nB.nNum[i];
1098             }
1099             if ( nA.bIsNeg )
1100                 return nA.nLen > nB.nLen;
1101             else
1102                 return nA.nLen < nB.nLen;
1103         }
1104         return !nB.bIsNeg;
1105     }
1106     return rVal1.nVal < rVal2.nVal;
1107 }
1108 
1109 // -----------------------------------------------------------------------
1110 
1111 sal_Bool operator >(const BigInt& rVal1, const BigInt& rVal2 )
1112 {
1113     if ( rVal1.bIsBig || rVal2.bIsBig )
1114     {
1115         BigInt nA, nB;
1116         nA.MakeBigInt( rVal1 );
1117         nB.MakeBigInt( rVal2 );
1118         if ( nA.bIsNeg == nB.bIsNeg )
1119         {
1120             if ( nA.nLen == nB.nLen )
1121             {
1122                 int i;
1123                 for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
1124                 {
1125                 }
1126 
1127                 if ( nA.bIsNeg )
1128                     return nA.nNum[i] < nB.nNum[i];
1129                 else
1130                     return nA.nNum[i] > nB.nNum[i];
1131             }
1132             if ( nA.bIsNeg )
1133                 return nA.nLen < nB.nLen;
1134             else
1135                 return nA.nLen > nB.nLen;
1136         }
1137         return !nA.bIsNeg;
1138     }
1139 
1140     return rVal1.nVal > rVal2.nVal;
1141 }
1142