bump product version to 4.1.6.2
[LibreOffice.git] / tools / source / generic / bigint.cxx
blob7104fe2e8657d30349838b8990b9438905c76caf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <math.h>
22 #include <tools/tools.h>
23 #include <tools/bigint.hxx>
24 #include <tools/string.hxx>
26 #include <string.h>
27 #include <ctype.h>
29 static const long MY_MAXLONG = 0x3fffffff;
30 static const long MY_MINLONG = -MY_MAXLONG;
31 static const long MY_MAXSHORT = 0x00007fff;
32 static const long MY_MINSHORT = -MY_MAXSHORT;
35 * The algorithms for Addition, Substraction, Multiplication and Divison
36 * of large numbers originate from SEMINUMERICAL ALGORITHMS by
37 * DONALD E. KNUTH in the series The Art of Computer Programming:
38 * chapter 4.3.1. The Classical Algorithms.
41 // TODO: Needs conversion to sal_uInt16/INT16/sal_uInt32/sal_Int32
42 void BigInt::MakeBigInt( const BigInt& rVal )
44 if ( rVal.bIsBig )
46 memcpy( (void*)this, (const void*)&rVal, sizeof( BigInt ) );
47 while ( nLen > 1 && nNum[nLen-1] == 0 )
48 nLen--;
50 else
52 long nTmp = rVal.nVal;
54 nVal = rVal.nVal;
55 bIsBig = sal_True;
56 if ( nTmp < 0 )
58 bIsNeg = sal_True;
59 nTmp = -nTmp;
61 else
62 bIsNeg = sal_False;
64 nNum[0] = (sal_uInt16)(nTmp & 0xffffL);
65 nNum[1] = (sal_uInt16)(nTmp >> 16);
66 if ( nTmp & 0xffff0000L )
67 nLen = 2;
68 else
69 nLen = 1;
73 void BigInt::Normalize()
75 if ( bIsBig )
77 while ( nLen > 1 && nNum[nLen-1] == 0 )
78 nLen--;
80 if ( nLen < 3 )
82 if ( nLen < 2 )
83 nVal = nNum[0];
84 else if ( nNum[1] & 0x8000 )
85 return;
86 else
87 nVal = ((long)nNum[1] << 16) + nNum[0];
89 bIsBig = sal_False;
91 if ( bIsNeg )
92 nVal = -nVal;
94 // else nVal is undefined !!! W.P.
96 // why? nVal is undefined ??? W.P.
97 else if ( nVal & 0xFFFF0000L )
98 nLen = 2;
99 else
100 nLen = 1;
103 void BigInt::Mult( const BigInt &rVal, sal_uInt16 nMul )
105 sal_uInt16 nK = 0;
106 for ( int i = 0; i < rVal.nLen; i++ )
108 sal_uInt32 nTmp = (sal_uInt32)rVal.nNum[i] * (sal_uInt32)nMul + nK;
109 nK = (sal_uInt16)(nTmp >> 16);
110 nNum[i] = (sal_uInt16)nTmp;
113 if ( nK )
115 nNum[rVal.nLen] = nK;
116 nLen = rVal.nLen + 1;
118 else
119 nLen = rVal.nLen;
121 bIsBig = sal_True;
122 bIsNeg = rVal.bIsNeg;
125 void BigInt::Div( sal_uInt16 nDiv, sal_uInt16& rRem )
127 sal_uInt32 nK = 0;
128 for ( int i = nLen - 1; i >= 0; i-- )
130 sal_uInt32 nTmp = (sal_uInt32)nNum[i] + (nK << 16);
131 nNum[i] = (sal_uInt16)(nTmp / nDiv);
132 nK = nTmp % nDiv;
134 rRem = (sal_uInt16)nK;
136 if ( nNum[nLen-1] == 0 )
137 nLen -= 1;
140 sal_Bool BigInt::IsLess( const BigInt& rVal ) const
142 if ( rVal.nLen < nLen)
143 return sal_True;
144 if ( rVal.nLen > nLen )
145 return sal_False;
147 int i;
148 for ( i = nLen - 1; i > 0 && nNum[i] == rVal.nNum[i]; i-- )
151 return rVal.nNum[i] < nNum[i];
154 void BigInt::AddLong( BigInt& rB, BigInt& rErg )
156 if ( bIsNeg == rB.bIsNeg )
158 int i;
159 char len;
161 // if length of the two values differ, fill remaining positions
162 // of the smaller value with zeros.
163 if (nLen >= rB.nLen)
165 len = nLen;
166 for (i = rB.nLen; i < len; i++)
167 rB.nNum[i] = 0;
169 else
171 len = rB.nLen;
172 for (i = nLen; i < len; i++)
173 nNum[i] = 0;
176 // Add numerals, starting from the back
177 long k;
178 long nZ = 0;
179 for (i = 0, k = 0; i < len; i++) {
180 nZ = (long)nNum[i] + (long)rB.nNum[i] + k;
181 if (nZ & 0xff0000L)
182 k = 1;
183 else
184 k = 0;
185 rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
187 // If an overflow occurred, add to solution
188 if (nZ & 0xff0000L) // or if(k)
190 rErg.nNum[i] = 1;
191 len++;
193 // Set length and sign
194 rErg.nLen = len;
195 rErg.bIsNeg = bIsNeg && rB.bIsNeg;
196 rErg.bIsBig = sal_True;
198 // If one of the values is negative, perform substraction instead
199 else if (bIsNeg)
201 bIsNeg = sal_False;
202 rB.SubLong(*this, rErg);
203 bIsNeg = sal_True;
205 else
207 rB.bIsNeg = sal_False;
208 SubLong(rB, rErg);
209 rB.bIsNeg = sal_True;
213 void BigInt::SubLong( BigInt& rB, BigInt& rErg )
215 if ( bIsNeg == rB.bIsNeg )
217 int i;
218 char len;
219 long nZ, k;
221 // if length of the two values differ, fill remaining positions
222 // of the smaller value with zeros.
223 if (nLen >= rB.nLen)
225 len = nLen;
226 for (i = rB.nLen; i < len; i++)
227 rB.nNum[i] = 0;
229 else
231 len = rB.nLen;
232 for (i = nLen; i < len; i++)
233 nNum[i] = 0;
236 if ( IsLess(rB) )
238 for (i = 0, k = 0; i < len; i++)
240 nZ = (long)nNum[i] - (long)rB.nNum[i] + k;
241 if (nZ < 0)
242 k = -1;
243 else
244 k = 0;
245 rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
247 rErg.bIsNeg = bIsNeg;
249 else
251 for (i = 0, k = 0; i < len; i++)
253 nZ = (long)rB.nNum[i] - (long)nNum[i] + k;
254 if (nZ < 0)
255 k = -1;
256 else
257 k = 0;
258 rErg.nNum[i] = (sal_uInt16)(nZ & 0xffffL);
260 // if a < b, revert sign
261 rErg.bIsNeg = !bIsNeg;
263 rErg.nLen = len;
264 rErg.bIsBig = sal_True;
266 // If one of the values is negative, perform addition instead
267 else if (bIsNeg)
269 bIsNeg = sal_False;
270 AddLong(rB, rErg);
271 bIsNeg = sal_True;
272 rErg.bIsNeg = sal_True;
274 else
276 rB.bIsNeg = sal_False;
277 AddLong(rB, rErg);
278 rB.bIsNeg = sal_True;
279 rErg.bIsNeg = sal_False;
283 void BigInt::MultLong( const BigInt& rB, BigInt& rErg ) const
285 int i, j;
286 sal_uInt32 nZ, k;
288 rErg.bIsNeg = bIsNeg != rB.bIsNeg;
289 rErg.bIsBig = sal_True;
290 rErg.nLen = nLen + rB.nLen;
292 for (i = 0; i < rErg.nLen; i++)
293 rErg.nNum[i] = 0;
295 for (j = 0; j < rB.nLen; j++)
297 for (i = 0, k = 0; i < nLen; i++)
299 nZ = (sal_uInt32)nNum[i] * (sal_uInt32)rB.nNum[j] +
300 (sal_uInt32)rErg.nNum[i + j] + k;
301 rErg.nNum[i + j] = (sal_uInt16)(nZ & 0xffffUL);
302 k = nZ >> 16;
304 rErg.nNum[i + j] = (sal_uInt16)k;
308 void BigInt::DivLong( const BigInt& rB, BigInt& rErg ) const
310 int i, j;
311 long nTmp;
312 sal_uInt16 nK, nQ, nMult;
313 short nLenB = rB.nLen;
314 short nLenB1 = rB.nLen - 1;
315 BigInt aTmpA, aTmpB;
317 nMult = (sal_uInt16)(0x10000L / ((long)rB.nNum[nLenB1] + 1));
319 aTmpA.Mult( *this, nMult );
320 if ( aTmpA.nLen == nLen )
322 aTmpA.nNum[aTmpA.nLen] = 0;
323 aTmpA.nLen++;
326 aTmpB.Mult( rB, nMult );
328 for (j = aTmpA.nLen - 1; j >= nLenB; j--)
329 { // guess divisor
330 nTmp = ( (long)aTmpA.nNum[j] << 16 ) + aTmpA.nNum[j - 1];
331 if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
332 nQ = 0xFFFF;
333 else
334 nQ = (sal_uInt16)(((sal_uInt32)nTmp) / aTmpB.nNum[nLenB1]);
336 if ( ((sal_uInt32)aTmpB.nNum[nLenB1 - 1] * nQ) >
337 ((((sal_uInt32)nTmp) - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
338 nQ--;
339 // Start division
340 nK = 0;
341 nTmp = 0;
342 for (i = 0; i < nLenB; i++)
344 nTmp = (long)aTmpA.nNum[j - nLenB + i]
345 - ((long)aTmpB.nNum[i] * nQ)
346 - nK;
347 aTmpA.nNum[j - nLenB + i] = (sal_uInt16)nTmp;
348 nK = (sal_uInt16) (nTmp >> 16);
349 if ( nK )
350 nK = (sal_uInt16)(0x10000UL - nK);
352 unsigned short& rNum( aTmpA.nNum[j - nLenB + i] );
353 rNum = rNum - nK; // MSVC yields a warning on -= here, so don't use it
354 if (aTmpA.nNum[j - nLenB + i] == 0)
355 rErg.nNum[j - nLenB] = nQ;
356 else
358 rErg.nNum[j - nLenB] = nQ - 1;
359 nK = 0;
360 for (i = 0; i < nLenB; i++)
362 nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
363 aTmpA.nNum[j - nLenB + i] = (sal_uInt16)(nTmp & 0xFFFFL);
364 if (nTmp & 0xFFFF0000L)
365 nK = 1;
366 else
367 nK = 0;
372 rErg.bIsNeg = bIsNeg != rB.bIsNeg;
373 rErg.bIsBig = sal_True;
374 rErg.nLen = nLen - rB.nLen + 1;
377 void BigInt::ModLong( const BigInt& rB, BigInt& rErg ) const
379 short i, j;
380 long nTmp;
381 sal_uInt16 nK, nQ, nMult;
382 short nLenB = rB.nLen;
383 short nLenB1 = rB.nLen - 1;
384 BigInt aTmpA, aTmpB;
386 nMult = (sal_uInt16)(0x10000L / ((long)rB.nNum[nLenB1] + 1));
388 aTmpA.Mult( *this, nMult);
389 if ( aTmpA.nLen == nLen )
391 aTmpA.nNum[aTmpA.nLen] = 0;
392 aTmpA.nLen++;
395 aTmpB.Mult( rB, nMult);
397 for (j = aTmpA.nLen - 1; j >= nLenB; j--)
398 { // Guess divisor
399 nTmp = ( (long)aTmpA.nNum[j] << 16 ) + aTmpA.nNum[j - 1];
400 if (aTmpA.nNum[j] == aTmpB.nNum[nLenB1])
401 nQ = 0xFFFF;
402 else
403 nQ = (sal_uInt16)(((sal_uInt32)nTmp) / aTmpB.nNum[nLenB1]);
405 if ( ((sal_uInt32)aTmpB.nNum[nLenB1 - 1] * nQ) >
406 ((((sal_uInt32)nTmp) - aTmpB.nNum[nLenB1] * nQ) << 16) + aTmpA.nNum[j - 2])
407 nQ--;
408 // Start division
409 nK = 0;
410 nTmp = 0;
411 for (i = 0; i < nLenB; i++)
413 nTmp = (long)aTmpA.nNum[j - nLenB + i]
414 - ((long)aTmpB.nNum[i] * nQ)
415 - nK;
416 aTmpA.nNum[j - nLenB + i] = (sal_uInt16)nTmp;
417 nK = (sal_uInt16) (nTmp >> 16);
418 if ( nK )
419 nK = (sal_uInt16)(0x10000UL - nK);
421 unsigned short& rNum( aTmpA.nNum[j - nLenB + i] );
422 rNum = rNum - nK;
423 if (aTmpA.nNum[j - nLenB + i] == 0)
424 rErg.nNum[j - nLenB] = nQ;
425 else
427 rErg.nNum[j - nLenB] = nQ - 1;
428 nK = 0;
429 for (i = 0; i < nLenB; i++) {
430 nTmp = aTmpA.nNum[j - nLenB + i] + aTmpB.nNum[i] + nK;
431 aTmpA.nNum[j - nLenB + i] = (sal_uInt16)(nTmp & 0xFFFFL);
432 if (nTmp & 0xFFFF0000L)
433 nK = 1;
434 else
435 nK = 0;
440 rErg = aTmpA;
441 rErg.Div( nMult, nQ );
444 sal_Bool BigInt::ABS_IsLess( const BigInt& rB ) const
446 if (bIsBig || rB.bIsBig)
448 BigInt nA, nB;
449 nA.MakeBigInt( *this );
450 nB.MakeBigInt( rB );
451 if (nA.nLen == nB.nLen)
453 int i;
454 for (i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i--)
457 return nA.nNum[i] < nB.nNum[i];
459 else
460 return nA.nLen < nB.nLen;
462 if ( nVal < 0 )
463 if ( rB.nVal < 0 )
464 return nVal > rB.nVal;
465 else
466 return nVal > -rB.nVal;
467 else
468 if ( rB.nVal < 0 )
469 return nVal < -rB.nVal;
470 else
471 return nVal < rB.nVal;
474 BigInt::BigInt( const BigInt& rBigInt )
476 if ( rBigInt.bIsBig )
477 memcpy( (void*)this, (const void*)&rBigInt, sizeof( BigInt ) );
478 else
480 bIsSet = rBigInt.bIsSet;
481 bIsBig = sal_False;
482 nVal = rBigInt.nVal;
486 BigInt::BigInt( const OUString& rString )
488 bIsSet = sal_True;
489 bIsNeg = sal_False;
490 bIsBig = sal_False;
491 nVal = 0;
493 sal_Bool bNeg = sal_False;
494 const sal_Unicode* p = rString.getStr();
495 if ( *p == '-' )
497 bNeg = sal_True;
498 p++;
500 while( *p >= '0' && *p <= '9' )
502 *this *= 10;
503 *this += *p - '0';
504 p++;
506 if ( bIsBig )
507 bIsNeg = bNeg;
508 else if( bNeg )
509 nVal = -nVal;
512 BigInt::BigInt( double nValue )
514 bIsSet = sal_True;
516 if ( nValue < 0 )
518 nValue *= -1;
519 bIsNeg = sal_True;
521 else
523 bIsNeg = sal_False;
526 if ( nValue < 1 )
528 bIsBig = sal_False;
529 nVal = 0;
531 else
533 bIsBig = sal_True;
535 int i=0;
537 while ( ( nValue > 65536.0 ) && ( i < MAX_DIGITS ) )
539 nNum[i] = (sal_uInt16) fmod( nValue, 65536.0 );
540 nValue -= nNum[i];
541 nValue /= 65536.0;
542 i++;
544 if ( i < MAX_DIGITS )
545 nNum[i++] = (sal_uInt16) nValue;
547 nLen = i;
549 if ( i < 3 )
550 Normalize();
554 BigInt::BigInt( sal_uInt32 nValue )
556 bIsSet = sal_True;
557 if ( nValue & 0x80000000UL )
559 bIsBig = sal_True;
560 bIsNeg = sal_False;
561 nNum[0] = (sal_uInt16)(nValue & 0xffffUL);
562 nNum[1] = (sal_uInt16)(nValue >> 16);
563 nLen = 2;
565 else
567 bIsBig = sal_False;
568 nVal = nValue;
572 BigInt::operator sal_uIntPtr() const
574 if ( !bIsBig )
575 return (sal_uInt32)nVal;
576 else if ( nLen == 2 )
578 sal_uInt32 nRet;
579 nRet = ((sal_uInt32)nNum[1]) << 16;
580 nRet += nNum[0];
581 return nRet;
583 return 0;
586 BigInt::operator double() const
588 if ( !bIsBig )
589 return (double) nVal;
590 else
592 int i = nLen-1;
593 double nRet = (double) ((sal_uInt32)nNum[i]);
595 while ( i )
597 nRet *= 65536.0;
598 i--;
599 nRet += (double) ((sal_uInt32)nNum[i]);
602 if ( bIsNeg )
603 nRet *= -1;
605 return nRet;
609 OUString BigInt::GetString() const
611 String aString;
613 if ( !bIsBig )
614 aString = OUString::number( nVal );
615 else
617 BigInt aTmp( *this );
618 BigInt a1000000000( 1000000000L );
619 aTmp.Abs();
623 BigInt a = aTmp;
624 a %= a1000000000;
625 aTmp /= a1000000000;
627 String aStr = aString;
628 if ( a.nVal < 100000000L )
629 { // leading 0s
630 aString = OUString::number( a.nVal + 1000000000L );
631 aString.Erase(0,1);
633 else
634 aString = OUString::number( a.nVal );
635 aString += aStr;
637 while( aTmp.bIsBig );
639 String aStr = aString;
640 if ( bIsNeg )
641 aString = OUString::number( -aTmp.nVal );
642 else
643 aString = OUString::number( aTmp.nVal );
644 aString += aStr;
647 return aString;
650 BigInt& BigInt::operator=( const BigInt& rBigInt )
652 if ( rBigInt.bIsBig )
653 memcpy( (void*)this, (const void*)&rBigInt, sizeof( BigInt ) );
654 else
656 bIsSet = rBigInt.bIsSet;
657 bIsBig = sal_False;
658 nVal = rBigInt.nVal;
660 return *this;
663 BigInt& BigInt::operator+=( const BigInt& rVal )
665 if ( !bIsBig && !rVal.bIsBig )
667 if( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG
668 && nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
669 { // No overflows may occur here
670 nVal += rVal.nVal;
671 return *this;
674 if( (nVal < 0) != (rVal.nVal < 0) )
675 { // No overflows may occur here
676 nVal += rVal.nVal;
677 return *this;
681 BigInt aTmp1, aTmp2;
682 aTmp1.MakeBigInt( *this );
683 aTmp2.MakeBigInt( rVal );
684 aTmp1.AddLong( aTmp2, *this );
685 Normalize();
686 return *this;
689 BigInt& BigInt::operator-=( const BigInt& rVal )
691 if ( !bIsBig && !rVal.bIsBig )
693 if ( nVal <= MY_MAXLONG && rVal.nVal <= MY_MAXLONG &&
694 nVal >= MY_MINLONG && rVal.nVal >= MY_MINLONG )
695 { // No overflows may occur here
696 nVal -= rVal.nVal;
697 return *this;
700 if ( (nVal < 0) == (rVal.nVal < 0) )
701 { // No overflows may occur here
702 nVal -= rVal.nVal;
703 return *this;
707 BigInt aTmp1, aTmp2;
708 aTmp1.MakeBigInt( *this );
709 aTmp2.MakeBigInt( rVal );
710 aTmp1.SubLong( aTmp2, *this );
711 Normalize();
712 return *this;
715 BigInt& BigInt::operator*=( const BigInt& rVal )
717 if ( !bIsBig && !rVal.bIsBig
718 && nVal <= MY_MAXSHORT && rVal.nVal <= MY_MAXSHORT
719 && nVal >= MY_MINSHORT && rVal.nVal >= MY_MINSHORT )
720 // TODO: not optimal !!! W.P.
721 { // No overflows may occur here
722 nVal *= rVal.nVal;
724 else
726 BigInt aTmp1, aTmp2;
727 aTmp1.MakeBigInt( rVal );
728 aTmp2.MakeBigInt( *this );
729 aTmp1.MultLong(aTmp2, *this);
730 Normalize();
732 return *this;
735 BigInt& BigInt::operator/=( const BigInt& rVal )
737 if ( !rVal.bIsBig )
739 if ( rVal.nVal == 0 )
741 OSL_FAIL( "BigInt::operator/ --> divide by zero" );
742 return *this;
745 if ( !bIsBig )
747 // No overflows may occur here
748 nVal /= rVal.nVal;
749 return *this;
752 if ( rVal.nVal == 1 )
753 return *this;
755 if ( rVal.nVal == -1 )
757 bIsNeg = !bIsNeg;
758 return *this;
761 if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
763 // Divide BigInt with an sal_uInt16
764 sal_uInt16 nTmp;
765 if ( rVal.nVal < 0 )
767 nTmp = (sal_uInt16) -rVal.nVal;
768 bIsNeg = !bIsNeg;
770 else
771 nTmp = (sal_uInt16) rVal.nVal;
773 Div( nTmp, nTmp );
774 Normalize();
775 return *this;
779 if ( ABS_IsLess( rVal ) )
781 *this = BigInt( (long)0 );
782 return *this;
785 // Divide BigInt with BigInt
786 BigInt aTmp1, aTmp2;
787 aTmp1.MakeBigInt( *this );
788 aTmp2.MakeBigInt( rVal );
789 aTmp1.DivLong(aTmp2, *this);
790 Normalize();
791 return *this;
794 BigInt& BigInt::operator%=( const BigInt& rVal )
796 if ( !rVal.bIsBig )
798 if ( rVal.nVal == 0 )
800 OSL_FAIL( "BigInt::operator/ --> divide by zero" );
801 return *this;
804 if ( !bIsBig )
806 // No overflows may occur here
807 nVal %= rVal.nVal;
808 return *this;
811 if ( rVal.nVal <= (long)0xFFFF && rVal.nVal >= -(long)0xFFFF )
813 // Divide Bigint by short
814 sal_uInt16 nTmp;
815 if ( rVal.nVal < 0 )
817 nTmp = (sal_uInt16) -rVal.nVal;
818 bIsNeg = !bIsNeg;
820 else
821 nTmp = (sal_uInt16) rVal.nVal;
823 Div( nTmp, nTmp );
824 *this = BigInt( (long)nTmp );
825 return *this;
829 if ( ABS_IsLess( rVal ) )
830 return *this;
832 // Divide BigInt with BigInt
833 BigInt aTmp1, aTmp2;
834 aTmp1.MakeBigInt( *this );
835 aTmp2.MakeBigInt( rVal );
836 aTmp1.ModLong(aTmp2, *this);
837 Normalize();
838 return *this;
841 sal_Bool operator==( const BigInt& rVal1, const BigInt& rVal2 )
843 if ( rVal1.bIsBig || rVal2.bIsBig )
845 BigInt nA, nB;
846 nA.MakeBigInt( rVal1 );
847 nB.MakeBigInt( rVal2 );
848 if ( nA.bIsNeg == nB.bIsNeg )
850 if ( nA.nLen == nB.nLen )
852 int i;
853 for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
857 return nA.nNum[i] == nB.nNum[i];
859 return sal_False;
861 return sal_False;
863 return rVal1.nVal == rVal2.nVal;
866 sal_Bool operator<( const BigInt& rVal1, const BigInt& rVal2 )
868 if ( rVal1.bIsBig || rVal2.bIsBig )
870 BigInt nA, nB;
871 nA.MakeBigInt( rVal1 );
872 nB.MakeBigInt( rVal2 );
873 if ( nA.bIsNeg == nB.bIsNeg )
875 if ( nA.nLen == nB.nLen )
877 int i;
878 for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
882 if ( nA.bIsNeg )
883 return nA.nNum[i] > nB.nNum[i];
884 else
885 return nA.nNum[i] < nB.nNum[i];
887 if ( nA.bIsNeg )
888 return nA.nLen > nB.nLen;
889 else
890 return nA.nLen < nB.nLen;
892 return !nB.bIsNeg;
894 return rVal1.nVal < rVal2.nVal;
897 sal_Bool operator >(const BigInt& rVal1, const BigInt& rVal2 )
899 if ( rVal1.bIsBig || rVal2.bIsBig )
901 BigInt nA, nB;
902 nA.MakeBigInt( rVal1 );
903 nB.MakeBigInt( rVal2 );
904 if ( nA.bIsNeg == nB.bIsNeg )
906 if ( nA.nLen == nB.nLen )
908 int i;
909 for ( i = nA.nLen - 1; i > 0 && nA.nNum[i] == nB.nNum[i]; i-- )
913 if ( nA.bIsNeg )
914 return nA.nNum[i] < nB.nNum[i];
915 else
916 return nA.nNum[i] > nB.nNum[i];
918 if ( nA.bIsNeg )
919 return nA.nLen < nB.nLen;
920 else
921 return nA.nLen > nB.nLen;
923 return !nA.bIsNeg;
926 return rVal1.nVal > rVal2.nVal;
929 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */