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