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