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