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