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