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 10cdf0e10cSrcweir * 11*89b56da7SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 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 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 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 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 163cdf0e10cSrcweir 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 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 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 315cdf0e10cSrcweir 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 342cdf0e10cSrcweir 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 413cdf0e10cSrcweir 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 482cdf0e10cSrcweir 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 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 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 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 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 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 648cdf0e10cSrcweir 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 689cdf0e10cSrcweir 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 732cdf0e10cSrcweir 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 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 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 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 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 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 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 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 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 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 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