1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bigint.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
35 #include <tools/tools.h>
37 #include <tools/bigint.hxx>
38 #include <tools/string.hxx>
39 #include <tools/debug.hxx>
44 static const long MY_MAXLONG
= 0x3fffffff;
45 static const long MY_MINLONG
= -MY_MAXLONG
;
46 static const long MY_MAXSHORT
= 0x00007fff;
47 static const long MY_MINSHORT
= -MY_MAXSHORT
;
49 /* Die ganzen Algorithmen zur Addition, Subtraktion, Multiplikation und
50 * Division von langen Zahlen stammen aus SEMINUMERICAL ALGORITHMS von
51 * DONALD E. KNUTH aus der Reihe The Art of Computer Programming. Zu finden
52 * sind diese Algorithmen im Kapitel 4.3.1. The Classical Algorithms.
55 // Muss auf UINT16/INT16/UINT32/INT32 umgestellt werden !!! W.P.
57 // -----------------------------------------------------------------------
59 void BigInt::MakeBigInt( const BigInt
& rVal
)
63 memcpy( (void*)this, (const void*)&rVal
, sizeof( BigInt
) );
64 while ( nLen
> 1 && nNum
[nLen
-1] == 0 )
69 long nTmp
= rVal
.nVal
;
81 nNum
[0] = (sal_uInt16
)(nTmp
& 0xffffL
);
82 nNum
[1] = (sal_uInt16
)(nTmp
>> 16);
84 if ( nTmp
& 0xffff0000L
)
95 // -----------------------------------------------------------------------
97 void BigInt::Normalize()
101 while ( nLen
> 1 && nNum
[nLen
-1] == 0 )
108 else if ( nNum
[1] & 0x8000 )
111 nVal
= ((long)nNum
[1] << 16) + nNum
[0];
118 // else ist nVal undefiniert !!! W.P.
120 // wozu, nLen ist doch undefiniert ??? W.P.
121 else if ( nVal
& 0xFFFF0000L
)
127 // -----------------------------------------------------------------------
129 void BigInt::Mult( const BigInt
&rVal
, sal_uInt16 nMul
)
132 for ( int i
= 0; i
< rVal
.nLen
; i
++ )
134 sal_uInt32 nTmp
= (sal_uInt32
)rVal
.nNum
[i
] * (sal_uInt32
)nMul
+ nK
;
135 nK
= (sal_uInt16
)(nTmp
>> 16);
136 nNum
[i
] = (sal_uInt16
)nTmp
;
141 nNum
[rVal
.nLen
] = nK
;
142 nLen
= rVal
.nLen
+ 1;
148 bIsNeg
= rVal
.bIsNeg
;
151 // -----------------------------------------------------------------------
153 void BigInt::Div( sal_uInt16 nDiv
, sal_uInt16
& rRem
)
156 for ( int i
= nLen
- 1; i
>= 0; i
-- )
158 sal_uInt32 nTmp
= (sal_uInt32
)nNum
[i
] + (nK
<< 16);
159 nNum
[i
] = (sal_uInt16
)(nTmp
/ nDiv
);
162 rRem
= (sal_uInt16
)nK
;
164 if ( nNum
[nLen
-1] == 0 )
168 // -----------------------------------------------------------------------
170 sal_Bool
BigInt::IsLess( const BigInt
& rVal
) const
172 if ( rVal
.nLen
< nLen
)
174 if ( rVal
.nLen
> nLen
)
178 for ( i
= nLen
- 1; i
> 0 && nNum
[i
] == rVal
.nNum
[i
]; i
-- )
181 return rVal
.nNum
[i
] < nNum
[i
];
184 // -----------------------------------------------------------------------
186 void BigInt::AddLong( BigInt
& rB
, BigInt
& rErg
)
188 if ( bIsNeg
== rB
.bIsNeg
)
193 // wenn die Zahlen unterschiedlich lang sind, sollte zunaechst bei
194 // der kleineren Zahl die fehlenden Ziffern mit 0 initialisert werden
198 for (i
= rB
.nLen
; i
< len
; i
++)
204 for (i
= nLen
; i
< len
; i
++)
208 // Die Ziffern werden von hinten nach vorne addiert
211 for (i
= 0, k
= 0; i
< len
; i
++) {
212 nZ
= (long)nNum
[i
] + (long)rB
.nNum
[i
] + k
;
217 rErg
.nNum
[i
] = (sal_uInt16
)(nZ
& 0xffffL
);
219 // Trat nach der letzten Addition ein Ueberlauf auf, muss dieser
220 // noch ins Ergebis uebernommen werden
221 if (nZ
& 0xff0000L
) // oder if(k)
226 // Die Laenge und das Vorzeichen setzen
228 rErg
.bIsNeg
= bIsNeg
&& rB
.bIsNeg
;
229 rErg
.bIsBig
= sal_True
;
231 // Wenn nur einer der beiden Operanten negativ ist, wird aus der
232 // Addition eine Subtaktion
236 rB
.SubLong(*this, rErg
);
241 rB
.bIsNeg
= sal_False
;
243 rB
.bIsNeg
= sal_True
;
247 // -----------------------------------------------------------------------
249 void BigInt::SubLong( BigInt
& rB
, BigInt
& rErg
)
251 if ( bIsNeg
== rB
.bIsNeg
)
257 // wenn die Zahlen unterschiedlich lang sind, sollte zunaechst bei
258 // der kleineren Zahl die fehlenden Ziffern mit 0 initialisert werden
262 for (i
= rB
.nLen
; i
< len
; i
++)
268 for (i
= nLen
; i
< len
; i
++)
274 for (i
= 0, k
= 0; i
< len
; i
++)
276 nZ
= (long)nNum
[i
] - (long)rB
.nNum
[i
] + k
;
281 rErg
.nNum
[i
] = (sal_uInt16
)(nZ
& 0xffffL
);
283 rErg
.bIsNeg
= bIsNeg
;
287 for (i
= 0, k
= 0; i
< len
; i
++)
289 nZ
= (long)rB
.nNum
[i
] - (long)nNum
[i
] + k
;
294 rErg
.nNum
[i
] = (sal_uInt16
)(nZ
& 0xffffL
);
296 // wenn a < b, dann Vorzeichen vom Ergebnis umdrehen
297 rErg
.bIsNeg
= !bIsNeg
;
300 rErg
.bIsBig
= sal_True
;
302 // Wenn nur einer der beiden Operanten negativ ist, wird aus der
303 // Subtaktion eine Addition
309 rErg
.bIsNeg
= sal_True
;
313 rB
.bIsNeg
= sal_False
;
315 rB
.bIsNeg
= sal_True
;
316 rErg
.bIsNeg
= sal_False
;
320 // -----------------------------------------------------------------------
322 void BigInt::MultLong( const BigInt
& rB
, BigInt
& rErg
) const
327 rErg
.bIsNeg
= bIsNeg
!= rB
.bIsNeg
;
328 rErg
.bIsBig
= sal_True
;
329 rErg
.nLen
= nLen
+ rB
.nLen
;
331 for (i
= 0; i
< rErg
.nLen
; i
++)
334 for (j
= 0; j
< rB
.nLen
; j
++)
336 for (i
= 0, k
= 0; i
< nLen
; i
++)
338 nZ
= (sal_uInt32
)nNum
[i
] * (sal_uInt32
)rB
.nNum
[j
] +
339 (sal_uInt32
)rErg
.nNum
[i
+ j
] + k
;
340 rErg
.nNum
[i
+ j
] = (sal_uInt16
)(nZ
& 0xffffUL
);
343 rErg
.nNum
[i
+ j
] = (sal_uInt16
)k
;
347 // -----------------------------------------------------------------------
349 void BigInt::DivLong( const BigInt
& rB
, BigInt
& rErg
) const
353 sal_uInt16 nK
, nQ
, nMult
;
354 short nLenB
= rB
.nLen
;
355 short nLenB1
= rB
.nLen
- 1;
358 nMult
= (sal_uInt16
)(0x10000L
/ ((long)rB
.nNum
[nLenB1
] + 1));
360 aTmpA
.Mult( *this, nMult
);
361 if ( aTmpA
.nLen
== nLen
)
363 aTmpA
.nNum
[aTmpA
.nLen
] = 0;
367 aTmpB
.Mult( rB
, nMult
);
369 for (j
= aTmpA
.nLen
- 1; j
>= nLenB
; j
--)
370 { // Raten des Divisors
371 nTmp
= ( (long)aTmpA
.nNum
[j
] << 16 ) + aTmpA
.nNum
[j
- 1];
372 if (aTmpA
.nNum
[j
] == aTmpB
.nNum
[nLenB1
])
375 nQ
= (sal_uInt16
)(((sal_uInt32
)nTmp
) / aTmpB
.nNum
[nLenB1
]);
377 if ( ((sal_uInt32
)aTmpB
.nNum
[nLenB1
- 1] * nQ
) >
378 ((((sal_uInt32
)nTmp
) - aTmpB
.nNum
[nLenB1
] * nQ
) << 16) + aTmpA
.nNum
[j
- 2])
380 // Und hier faengt das Teilen an
383 for (i
= 0; i
< nLenB
; i
++)
385 nTmp
= (long)aTmpA
.nNum
[j
- nLenB
+ i
]
386 - ((long)aTmpB
.nNum
[i
] * nQ
)
388 aTmpA
.nNum
[j
- nLenB
+ i
] = (sal_uInt16
)nTmp
;
389 nK
= (sal_uInt16
) (nTmp
>> 16);
391 nK
= (sal_uInt16
)(0x10000UL
- nK
);
393 unsigned short& rNum( aTmpA
.nNum
[j
- nLenB
+ i
] );
394 rNum
= rNum
- nK
; // MSVC yields a warning on -= here, so don't use it
395 if (aTmpA
.nNum
[j
- nLenB
+ i
] == 0)
396 rErg
.nNum
[j
- nLenB
] = nQ
;
399 rErg
.nNum
[j
- nLenB
] = nQ
- 1;
401 for (i
= 0; i
< nLenB
; i
++)
403 nTmp
= aTmpA
.nNum
[j
- nLenB
+ i
] + aTmpB
.nNum
[i
] + nK
;
404 aTmpA
.nNum
[j
- nLenB
+ i
] = (sal_uInt16
)(nTmp
& 0xFFFFL
);
405 if (nTmp
& 0xFFFF0000L
)
413 rErg
.bIsNeg
= bIsNeg
!= rB
.bIsNeg
;
414 rErg
.bIsBig
= sal_True
;
415 rErg
.nLen
= nLen
- rB
.nLen
+ 1;
418 // -----------------------------------------------------------------------
420 void BigInt::ModLong( const BigInt
& rB
, BigInt
& rErg
) const
424 sal_uInt16 nK
, nQ
, nMult
;
425 short nLenB
= rB
.nLen
;
426 short nLenB1
= rB
.nLen
- 1;
429 nMult
= (sal_uInt16
)(0x10000L
/ ((long)rB
.nNum
[nLenB1
] + 1));
431 aTmpA
.Mult( *this, nMult
);
432 if ( aTmpA
.nLen
== nLen
)
434 aTmpA
.nNum
[aTmpA
.nLen
] = 0;
438 aTmpB
.Mult( rB
, nMult
);
440 for (j
= aTmpA
.nLen
- 1; j
>= nLenB
; j
--)
441 { // Raten des Divisors
442 nTmp
= ( (long)aTmpA
.nNum
[j
] << 16 ) + aTmpA
.nNum
[j
- 1];
443 if (aTmpA
.nNum
[j
] == aTmpB
.nNum
[nLenB1
])
446 nQ
= (sal_uInt16
)(((sal_uInt32
)nTmp
) / aTmpB
.nNum
[nLenB1
]);
448 if ( ((sal_uInt32
)aTmpB
.nNum
[nLenB1
- 1] * nQ
) >
449 ((((sal_uInt32
)nTmp
) - aTmpB
.nNum
[nLenB1
] * nQ
) << 16) + aTmpA
.nNum
[j
- 2])
451 // Und hier faengt das Teilen an
454 for (i
= 0; i
< nLenB
; i
++)
456 nTmp
= (long)aTmpA
.nNum
[j
- nLenB
+ i
]
457 - ((long)aTmpB
.nNum
[i
] * nQ
)
459 aTmpA
.nNum
[j
- nLenB
+ i
] = (sal_uInt16
)nTmp
;
460 nK
= (sal_uInt16
) (nTmp
>> 16);
462 nK
= (sal_uInt16
)(0x10000UL
- nK
);
464 unsigned short& rNum( aTmpA
.nNum
[j
- nLenB
+ i
] );
466 if (aTmpA
.nNum
[j
- nLenB
+ i
] == 0)
467 rErg
.nNum
[j
- nLenB
] = nQ
;
470 rErg
.nNum
[j
- nLenB
] = nQ
- 1;
472 for (i
= 0; i
< nLenB
; i
++) {
473 nTmp
= aTmpA
.nNum
[j
- nLenB
+ i
] + aTmpB
.nNum
[i
] + nK
;
474 aTmpA
.nNum
[j
- nLenB
+ i
] = (sal_uInt16
)(nTmp
& 0xFFFFL
);
475 if (nTmp
& 0xFFFF0000L
)
484 rErg
.Div( nMult
, nQ
);
487 // -----------------------------------------------------------------------
489 sal_Bool
BigInt::ABS_IsLess( const BigInt
& rB
) const
491 if (bIsBig
|| rB
.bIsBig
)
494 nA
.MakeBigInt( *this );
496 if (nA
.nLen
== nB
.nLen
)
499 for (i
= nA
.nLen
- 1; i
> 0 && nA
.nNum
[i
] == nB
.nNum
[i
]; i
--)
502 return nA
.nNum
[i
] < nB
.nNum
[i
];
505 return nA
.nLen
< nB
.nLen
;
509 return nVal
> rB
.nVal
;
511 return nVal
> -rB
.nVal
;
514 return nVal
< -rB
.nVal
;
516 return nVal
< rB
.nVal
;
519 // -----------------------------------------------------------------------
521 BigInt::BigInt( const BigInt
& rBigInt
)
523 if ( rBigInt
.bIsBig
)
524 memcpy( (void*)this, (const void*)&rBigInt
, sizeof( BigInt
) );
527 bIsSet
= rBigInt
.bIsSet
;
533 // -----------------------------------------------------------------------
535 BigInt::BigInt( const ByteString
& rString
)
542 sal_Bool bNeg
= sal_False
;
543 const sal_Char
* p
= rString
.GetBuffer();
549 while( *p
>= '0' && *p
<= '9' )
561 // -----------------------------------------------------------------------
563 BigInt::BigInt( const UniString
& rString
)
570 sal_Bool bNeg
= sal_False
;
571 const sal_Unicode
* p
= rString
.GetBuffer();
577 while( *p
>= '0' && *p
<= '9' )
589 // -----------------------------------------------------------------------
591 BigInt::BigInt( double nValue
)
616 while ( ( nValue
> 65536.0 ) && ( i
< MAX_DIGITS
) )
618 nNum
[i
] = (sal_uInt16
) fmod( nValue
, 65536.0 );
623 if ( i
< MAX_DIGITS
)
624 nNum
[i
++] = (sal_uInt16
) nValue
;
633 // -----------------------------------------------------------------------
635 BigInt::BigInt( sal_uInt32 nValue
)
638 if ( nValue
& 0x80000000UL
)
642 nNum
[0] = (sal_uInt16
)(nValue
& 0xffffUL
);
643 nNum
[1] = (sal_uInt16
)(nValue
>> 16);
653 // -----------------------------------------------------------------------
655 BigInt::operator ULONG() const
658 return (sal_uInt32
)nVal
;
659 else if ( nLen
== 2 )
662 nRet
= ((sal_uInt32
)nNum
[1]) << 16;
669 // -----------------------------------------------------------------------
671 BigInt::operator double() const
674 return (double) nVal
;
678 double nRet
= (double) ((sal_uInt32
)nNum
[i
]);
684 nRet
+= (double) ((sal_uInt32
)nNum
[i
]);
694 // -----------------------------------------------------------------------
696 ByteString
BigInt::GetByteString() const
701 aString
= ByteString::CreateFromInt32( nVal
);
704 BigInt
aTmp( *this );
705 BigInt
a1000000000( 1000000000L );
714 ByteString aStr
= aString
;
715 if ( a
.nVal
< 100000000L )
717 aString
= ByteString::CreateFromInt32( a
.nVal
+ 1000000000L );
718 aString
.Erase( 0, 1 );
721 aString
= ByteString::CreateFromInt32( a
.nVal
);
724 while( aTmp
.bIsBig
);
726 ByteString aStr
= aString
;
728 aString
= ByteString::CreateFromInt32( -aTmp
.nVal
);
730 aString
= ByteString::CreateFromInt32( aTmp
.nVal
);
737 // -----------------------------------------------------------------------
739 UniString
BigInt::GetString() const
744 aString
= UniString::CreateFromInt32( nVal
);
747 BigInt
aTmp( *this );
748 BigInt
a1000000000( 1000000000L );
757 UniString aStr
= aString
;
758 if ( a
.nVal
< 100000000L )
760 aString
= UniString::CreateFromInt32( a
.nVal
+ 1000000000L );
764 aString
= UniString::CreateFromInt32( a
.nVal
);
767 while( aTmp
.bIsBig
);
769 UniString aStr
= aString
;
771 aString
= UniString::CreateFromInt32( -aTmp
.nVal
);
773 aString
= UniString::CreateFromInt32( aTmp
.nVal
);
780 // -----------------------------------------------------------------------
782 BigInt
& BigInt::operator=( const BigInt
& rBigInt
)
784 if ( rBigInt
.bIsBig
)
785 memcpy( (void*)this, (const void*)&rBigInt
, sizeof( BigInt
) );
788 bIsSet
= rBigInt
.bIsSet
;
795 // -----------------------------------------------------------------------
797 BigInt
& BigInt::operator+=( const BigInt
& rVal
)
799 if ( !bIsBig
&& !rVal
.bIsBig
)
801 if( nVal
<= MY_MAXLONG
&& rVal
.nVal
<= MY_MAXLONG
802 && nVal
>= MY_MINLONG
&& rVal
.nVal
>= MY_MINLONG
)
803 { // wir bewegen uns im ungefaehrlichem Bereich
808 if( (nVal
< 0) != (rVal
.nVal
< 0) )
809 { // wir bewegen uns im ungefaehrlichem Bereich
816 aTmp1
.MakeBigInt( *this );
817 aTmp2
.MakeBigInt( rVal
);
818 aTmp1
.AddLong( aTmp2
, *this );
823 // -----------------------------------------------------------------------
825 BigInt
& BigInt::operator-=( const BigInt
& rVal
)
827 if ( !bIsBig
&& !rVal
.bIsBig
)
829 if ( nVal
<= MY_MAXLONG
&& rVal
.nVal
<= MY_MAXLONG
&&
830 nVal
>= MY_MINLONG
&& rVal
.nVal
>= MY_MINLONG
)
831 { // wir bewegen uns im ungefaehrlichem Bereich
836 if ( (nVal
< 0) == (rVal
.nVal
< 0) )
837 { // wir bewegen uns im ungefaehrlichem Bereich
844 aTmp1
.MakeBigInt( *this );
845 aTmp2
.MakeBigInt( rVal
);
846 aTmp1
.SubLong( aTmp2
, *this );
851 // -----------------------------------------------------------------------
853 BigInt
& BigInt::operator*=( const BigInt
& rVal
)
855 if ( !bIsBig
&& !rVal
.bIsBig
856 && nVal
<= MY_MAXSHORT
&& rVal
.nVal
<= MY_MAXSHORT
857 && nVal
>= MY_MINSHORT
&& rVal
.nVal
>= MY_MINSHORT
)
858 // nicht optimal !!! W.P.
859 { // wir bewegen uns im ungefaehrlichem Bereich
865 aTmp1
.MakeBigInt( rVal
);
866 aTmp2
.MakeBigInt( *this );
867 aTmp1
.MultLong(aTmp2
, *this);
873 // -----------------------------------------------------------------------
875 BigInt
& BigInt::operator/=( const BigInt
& rVal
)
879 if ( rVal
.nVal
== 0 )
881 DBG_ERROR( "BigInt::operator/ --> divide by zero" );
887 // wir bewegen uns im ungefaehrlichem Bereich
892 if ( rVal
.nVal
== 1 )
895 if ( rVal
.nVal
== -1 )
901 if ( rVal
.nVal
<= (long)0xFFFF && rVal
.nVal
>= -(long)0xFFFF )
903 // ein BigInt durch ein sal_uInt16 teilen
907 nTmp
= (sal_uInt16
) -rVal
.nVal
;
911 nTmp
= (sal_uInt16
) rVal
.nVal
;
919 if ( ABS_IsLess( rVal
) )
921 *this = BigInt( (long)0 );
925 // BigInt durch BigInt teilen
927 aTmp1
.MakeBigInt( *this );
928 aTmp2
.MakeBigInt( rVal
);
929 aTmp1
.DivLong(aTmp2
, *this);
934 // -----------------------------------------------------------------------
936 void BigInt::DivMod( const BigInt
& rVal
, BigInt
& rMod
)
940 if ( rVal
.nVal
== 0 )
942 DBG_ERROR( "BigInt::operator/ --> divide by zero" );
948 // wir bewegen uns im ungefaehrlichem Bereich
949 rMod
= BigInt( nVal
% rVal
.nVal
);
954 if ( rVal
.nVal
== 1 )
956 rMod
= BigInt( (long)0 );
960 if ( rVal
.nVal
== -1 )
962 rMod
= BigInt( (long)0 );
967 if ( rVal
.nVal
<= (long)0xFFFF && rVal
.nVal
>= -(long)0xFFFF )
969 // ein BigInt durch ein sal_uInt16 teilen
973 nTmp
= (sal_uInt16
) -rVal
.nVal
;
977 nTmp
= (sal_uInt16
) rVal
.nVal
;
980 rMod
= BigInt( (long)nTmp
);
986 if ( ABS_IsLess( rVal
) )
989 *this = BigInt( (long)0 );
993 // BigInt durch BigInt teilen
995 aTmp1
.MakeBigInt( *this );
996 aTmp2
.MakeBigInt( rVal
);
997 aTmp1
.DivLong(aTmp2
, *this);
999 aTmp1
.ModLong(aTmp2
, rMod
); // nicht optimal
1003 // -----------------------------------------------------------------------
1005 BigInt
& BigInt::operator%=( const BigInt
& rVal
)
1009 if ( rVal
.nVal
== 0 )
1011 DBG_ERROR( "BigInt::operator/ --> divide by zero" );
1017 // wir bewegen uns im ungefaehrlichem Bereich
1022 if ( rVal
.nVal
<= (long)0xFFFF && rVal
.nVal
>= -(long)0xFFFF )
1024 // ein BigInt durch ein short teilen
1026 if ( rVal
.nVal
< 0 )
1028 nTmp
= (sal_uInt16
) -rVal
.nVal
;
1032 nTmp
= (sal_uInt16
) rVal
.nVal
;
1035 *this = BigInt( (long)nTmp
);
1040 if ( ABS_IsLess( rVal
) )
1043 // BigInt durch BigInt teilen
1044 BigInt aTmp1
, aTmp2
;
1045 aTmp1
.MakeBigInt( *this );
1046 aTmp2
.MakeBigInt( rVal
);
1047 aTmp1
.ModLong(aTmp2
, *this);
1052 // -----------------------------------------------------------------------
1054 sal_Bool
operator==( const BigInt
& rVal1
, const BigInt
& rVal2
)
1056 if ( rVal1
.bIsBig
|| rVal2
.bIsBig
)
1059 nA
.MakeBigInt( rVal1
);
1060 nB
.MakeBigInt( rVal2
);
1061 if ( nA
.bIsNeg
== nB
.bIsNeg
)
1063 if ( nA
.nLen
== nB
.nLen
)
1066 for ( i
= nA
.nLen
- 1; i
> 0 && nA
.nNum
[i
] == nB
.nNum
[i
]; i
-- )
1070 return nA
.nNum
[i
] == nB
.nNum
[i
];
1076 return rVal1
.nVal
== rVal2
.nVal
;
1079 // -----------------------------------------------------------------------
1081 sal_Bool
operator<( const BigInt
& rVal1
, const BigInt
& rVal2
)
1083 if ( rVal1
.bIsBig
|| rVal2
.bIsBig
)
1086 nA
.MakeBigInt( rVal1
);
1087 nB
.MakeBigInt( rVal2
);
1088 if ( nA
.bIsNeg
== nB
.bIsNeg
)
1090 if ( nA
.nLen
== nB
.nLen
)
1093 for ( i
= nA
.nLen
- 1; i
> 0 && nA
.nNum
[i
] == nB
.nNum
[i
]; i
-- )
1098 return nA
.nNum
[i
] > nB
.nNum
[i
];
1100 return nA
.nNum
[i
] < nB
.nNum
[i
];
1103 return nA
.nLen
> nB
.nLen
;
1105 return nA
.nLen
< nB
.nLen
;
1109 return rVal1
.nVal
< rVal2
.nVal
;
1112 // -----------------------------------------------------------------------
1114 sal_Bool
operator >(const BigInt
& rVal1
, const BigInt
& rVal2
)
1116 if ( rVal1
.bIsBig
|| rVal2
.bIsBig
)
1119 nA
.MakeBigInt( rVal1
);
1120 nB
.MakeBigInt( rVal2
);
1121 if ( nA
.bIsNeg
== nB
.bIsNeg
)
1123 if ( nA
.nLen
== nB
.nLen
)
1126 for ( i
= nA
.nLen
- 1; i
> 0 && nA
.nNum
[i
] == nB
.nNum
[i
]; i
-- )
1131 return nA
.nNum
[i
] < nB
.nNum
[i
];
1133 return nA
.nNum
[i
] > nB
.nNum
[i
];
1136 return nA
.nLen
< nB
.nLen
;
1138 return nA
.nLen
> nB
.nLen
;
1143 return rVal1
.nVal
> rVal2
.nVal
;