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