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