1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.math; 19 20/** 21 * The library implements some logical operations over {@code BigInteger}. The 22 * operations provided are listed below. 23 * <ul type="circle"> 24 * <li>not</li> 25 * <li>and</li> 26 * <li>andNot</li> 27 * <li>or</li> 28 * <li>xor</li> 29 * </ul> 30 */ 31class Logical { 32 33 /** Just to denote that this class can't be instantiated. */ 34 35 private Logical() {} 36 37 38 /** @see BigInteger#not() */ 39 static BigInteger not(BigInteger val) { 40 if (val.sign == 0) { 41 return BigInteger.MINUS_ONE; 42 } 43 if (val.equals(BigInteger.MINUS_ONE)) { 44 return BigInteger.ZERO; 45 } 46 int[] resDigits = new int[val.numberLength + 1]; 47 int i; 48 49 if (val.sign > 0) { 50 // ~val = -val + 1 51 if (val.digits[val.numberLength - 1] != -1) { 52 for (i = 0; val.digits[i] == -1; i++) { 53 ; 54 } 55 } else { 56 for (i = 0; (i < val.numberLength) && (val.digits[i] == -1); i++) { 57 ; 58 } 59 if (i == val.numberLength) { 60 resDigits[i] = 1; 61 return new BigInteger(-val.sign, i + 1, resDigits); 62 } 63 } 64 // Here a carry 1 was generated 65 } else {// (val.sign < 0) 66 // ~val = -val - 1 67 for (i = 0; val.digits[i] == 0; i++) { 68 resDigits[i] = -1; 69 } 70 // Here a borrow -1 was generated 71 } 72 // Now, the carry/borrow can be absorbed 73 resDigits[i] = val.digits[i] + val.sign; 74 // Copying the remaining unchanged digit 75 for (i++; i < val.numberLength; i++) { 76 resDigits[i] = val.digits[i]; 77 } 78 return new BigInteger(-val.sign, i, resDigits); 79 } 80 81 /** @see BigInteger#and(BigInteger) */ 82 static BigInteger and(BigInteger val, BigInteger that) { 83 if (that.sign == 0 || val.sign == 0) { 84 return BigInteger.ZERO; 85 } 86 if (that.equals(BigInteger.MINUS_ONE)){ 87 return val; 88 } 89 if (val.equals(BigInteger.MINUS_ONE)) { 90 return that; 91 } 92 93 if (val.sign > 0) { 94 if (that.sign > 0) { 95 return andPositive(val, that); 96 } else { 97 return andDiffSigns(val, that); 98 } 99 } else { 100 if (that.sign > 0) { 101 return andDiffSigns(that, val); 102 } else if (val.numberLength > that.numberLength) { 103 return andNegative(val, that); 104 } else { 105 return andNegative(that, val); 106 } 107 } 108 } 109 110 /** @return sign = 1, magnitude = val.magnitude & that.magnitude*/ 111 static BigInteger andPositive(BigInteger val, BigInteger that) { 112 // PRE: both arguments are positive 113 int resLength = Math.min(val.numberLength, that.numberLength); 114 int i = Math.max(val.getFirstNonzeroDigit(), that.getFirstNonzeroDigit()); 115 116 if (i >= resLength) { 117 return BigInteger.ZERO; 118 } 119 120 int[] resDigits = new int[resLength]; 121 for ( ; i < resLength; i++) { 122 resDigits[i] = val.digits[i] & that.digits[i]; 123 } 124 125 return new BigInteger(1, resLength, resDigits); 126 } 127 128 /** @return sign = positive.magnitude & magnitude = -negative.magnitude */ 129 static BigInteger andDiffSigns(BigInteger positive, BigInteger negative) { 130 // PRE: positive is positive and negative is negative 131 int iPos = positive.getFirstNonzeroDigit(); 132 int iNeg = negative.getFirstNonzeroDigit(); 133 134 // Look if the trailing zeros of the negative will "blank" all 135 // the positive digits 136 if (iNeg >= positive.numberLength) { 137 return BigInteger.ZERO; 138 } 139 int resLength = positive.numberLength; 140 int[] resDigits = new int[resLength]; 141 142 // Must start from max(iPos, iNeg) 143 int i = Math.max(iPos, iNeg); 144 if (i == iNeg) { 145 resDigits[i] = -negative.digits[i] & positive.digits[i]; 146 i++; 147 } 148 int limit = Math.min(negative.numberLength, positive.numberLength); 149 for ( ; i < limit; i++) { 150 resDigits[i] = ~negative.digits[i] & positive.digits[i]; 151 } 152 // if the negative was shorter must copy the remaining digits 153 // from positive 154 if (i >= negative.numberLength) { 155 for ( ; i < positive.numberLength; i++) { 156 resDigits[i] = positive.digits[i]; 157 } 158 } // else positive ended and must "copy" virtual 0's, do nothing then 159 160 return new BigInteger(1, resLength, resDigits); 161 } 162 163 /** @return sign = -1, magnitude = -(-longer.magnitude & -shorter.magnitude)*/ 164 static BigInteger andNegative(BigInteger longer, BigInteger shorter) { 165 // PRE: longer and shorter are negative 166 // PRE: longer has at least as many digits as shorter 167 int iLonger = longer.getFirstNonzeroDigit(); 168 int iShorter = shorter.getFirstNonzeroDigit(); 169 170 // Does shorter matter? 171 if (iLonger >= shorter.numberLength) { 172 return longer; 173 } 174 175 int resLength; 176 int[] resDigits; 177 int i = Math.max(iShorter, iLonger); 178 int digit; 179 if (iShorter > iLonger) { 180 digit = -shorter.digits[i] & ~longer.digits[i]; 181 } else if (iShorter < iLonger) { 182 digit = ~shorter.digits[i] & -longer.digits[i]; 183 } else { 184 digit = -shorter.digits[i] & -longer.digits[i]; 185 } 186 if (digit == 0) { 187 for (i++; i < shorter.numberLength && (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++) 188 ; // digit = ~longer.digits[i] & ~shorter.digits[i] 189 if (digit == 0) { 190 // shorter has only the remaining virtual sign bits 191 for ( ; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++) 192 ; 193 if (digit == 0) { 194 resLength = longer.numberLength + 1; 195 resDigits = new int[resLength]; 196 resDigits[resLength - 1] = 1; 197 198 return new BigInteger(-1, resLength, resDigits); 199 } 200 } 201 } 202 resLength = longer.numberLength; 203 resDigits = new int[resLength]; 204 resDigits[i] = -digit; 205 for (i++; i < shorter.numberLength; i++){ 206 // resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];) 207 resDigits[i] = longer.digits[i] | shorter.digits[i]; 208 } 209 // shorter has only the remaining virtual sign bits 210 for ( ; i < longer.numberLength; i++){ 211 resDigits[i] = longer.digits[i]; 212 } 213 214 return new BigInteger(-1, resLength, resDigits); 215 } 216 217 /** @see BigInteger#andNot(BigInteger) */ 218 static BigInteger andNot(BigInteger val, BigInteger that) { 219 if (that.sign == 0 ) { 220 return val; 221 } 222 if (val.sign == 0) { 223 return BigInteger.ZERO; 224 } 225 if (val.equals(BigInteger.MINUS_ONE)) { 226 return that.not(); 227 } 228 if (that.equals(BigInteger.MINUS_ONE)){ 229 return BigInteger.ZERO; 230 } 231 232 //if val == that, return 0 233 234 if (val.sign > 0) { 235 if (that.sign > 0) { 236 return andNotPositive(val, that); 237 } else { 238 return andNotPositiveNegative(val, that); 239 } 240 } else { 241 if (that.sign > 0) { 242 return andNotNegativePositive(val, that); 243 } else { 244 return andNotNegative(val, that); 245 } 246 } 247 } 248 249 /** @return sign = 1, magnitude = val.magnitude & ~that.magnitude*/ 250 static BigInteger andNotPositive(BigInteger val, BigInteger that) { 251 // PRE: both arguments are positive 252 int[] resDigits = new int[val.numberLength]; 253 254 int limit = Math.min(val.numberLength, that.numberLength); 255 int i; 256 for (i = val.getFirstNonzeroDigit(); i < limit; i++) { 257 resDigits[i] = val.digits[i] & ~that.digits[i]; 258 } 259 for ( ; i < val.numberLength; i++) { 260 resDigits[i] = val.digits[i]; 261 } 262 263 return new BigInteger(1, val.numberLength, resDigits); 264 } 265 266 /** @return sign = 1, magnitude = positive.magnitude & ~(-negative.magnitude)*/ 267 static BigInteger andNotPositiveNegative(BigInteger positive, BigInteger negative) { 268 // PRE: positive > 0 && negative < 0 269 int iNeg = negative.getFirstNonzeroDigit(); 270 int iPos = positive.getFirstNonzeroDigit(); 271 272 if (iNeg >= positive.numberLength) { 273 return positive; 274 } 275 276 int resLength = Math.min(positive.numberLength, negative.numberLength); 277 int[] resDigits = new int[resLength]; 278 279 // Always start from first non zero of positive 280 int i = iPos; 281 for ( ; i < iNeg; i++) { 282 // resDigits[i] = positive.digits[i] & -1 (~0) 283 resDigits[i] = positive.digits[i]; 284 } 285 if (i == iNeg) { 286 resDigits[i] = positive.digits[i] & (negative.digits[i] - 1); 287 i++; 288 } 289 for ( ; i < resLength; i++) { 290 // resDigits[i] = positive.digits[i] & ~(~negative.digits[i]); 291 resDigits[i] = positive.digits[i] & negative.digits[i]; 292 } 293 294 return new BigInteger(1, resLength, resDigits); 295 } 296 297 /** @return sign = -1, magnitude = -(-negative.magnitude & ~positive.magnitude)*/ 298 static BigInteger andNotNegativePositive(BigInteger negative, BigInteger positive) { 299 // PRE: negative < 0 && positive > 0 300 int resLength; 301 int[] resDigits; 302 int limit; 303 int digit; 304 305 int iNeg = negative.getFirstNonzeroDigit(); 306 int iPos = positive.getFirstNonzeroDigit(); 307 308 if (iNeg >= positive.numberLength) { 309 return negative; 310 } 311 312 resLength = Math.max(negative.numberLength, positive.numberLength); 313 int i = iNeg; 314 if (iPos > iNeg) { 315 resDigits = new int[resLength]; 316 limit = Math.min(negative.numberLength, iPos); 317 for ( ; i < limit; i++) { 318 // 1st case: resDigits [i] = -(-negative.digits[i] & (~0)) 319 // otherwise: resDigits[i] = ~(~negative.digits[i] & ~0) ; 320 resDigits[i] = negative.digits[i]; 321 } 322 if (i == negative.numberLength) { 323 for (i = iPos; i < positive.numberLength; i++) { 324 // resDigits[i] = ~(~positive.digits[i] & -1); 325 resDigits[i] = positive.digits[i]; 326 } 327 } 328 } else { 329 digit = -negative.digits[i] & ~positive.digits[i]; 330 if (digit == 0) { 331 limit = Math.min(positive.numberLength, negative.numberLength); 332 for (i++; i < limit && (digit = ~(negative.digits[i] | positive.digits[i])) == 0; i++) 333 ; // digit = ~negative.digits[i] & ~positive.digits[i] 334 if (digit == 0) { 335 // the shorter has only the remaining virtual sign bits 336 for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++) 337 ; // digit = -1 & ~positive.digits[i] 338 for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++) 339 ; // digit = ~negative.digits[i] & ~0 340 if (digit == 0) { 341 resLength++; 342 resDigits = new int[resLength]; 343 resDigits[resLength - 1] = 1; 344 345 return new BigInteger(-1, resLength, resDigits); 346 } 347 } 348 } 349 resDigits = new int[resLength]; 350 resDigits[i] = -digit; 351 i++; 352 } 353 354 limit = Math.min(positive.numberLength, negative.numberLength); 355 for ( ; i < limit; i++) { 356 //resDigits[i] = ~(~negative.digits[i] & ~positive.digits[i]); 357 resDigits[i] = negative.digits[i] | positive.digits[i]; 358 } 359 // Actually one of the next two cycles will be executed 360 for ( ; i < negative.numberLength; i++) { 361 resDigits[i] = negative.digits[i]; 362 } 363 for ( ; i < positive.numberLength; i++) { 364 resDigits[i] = positive.digits[i]; 365 } 366 367 return new BigInteger(-1, resLength, resDigits); 368 } 369 370 /** @return sign = 1, magnitude = -val.magnitude & ~(-that.magnitude)*/ 371 static BigInteger andNotNegative(BigInteger val, BigInteger that) { 372 // PRE: val < 0 && that < 0 373 int iVal = val.getFirstNonzeroDigit(); 374 int iThat = that.getFirstNonzeroDigit(); 375 376 if (iVal >= that.numberLength) { 377 return BigInteger.ZERO; 378 } 379 380 int resLength = that.numberLength; 381 int[] resDigits = new int[resLength]; 382 int limit; 383 int i = iVal; 384 if (iVal < iThat) { 385 // resDigits[i] = -val.digits[i] & -1; 386 resDigits[i] = -val.digits[i]; 387 limit = Math.min(val.numberLength, iThat); 388 for (i++; i < limit; i++) { 389 // resDigits[i] = ~val.digits[i] & -1; 390 resDigits[i] = ~val.digits[i]; 391 } 392 if (i == val.numberLength) { 393 for ( ; i < iThat; i++) { 394 // resDigits[i] = -1 & -1; 395 resDigits[i] = -1; 396 } 397 // resDigits[i] = -1 & ~-that.digits[i]; 398 resDigits[i] = that.digits[i] - 1; 399 } else { 400 // resDigits[i] = ~val.digits[i] & ~-that.digits[i]; 401 resDigits[i] = ~val.digits[i] & (that.digits[i] - 1); 402 } 403 } else if (iThat < iVal ) { 404 // resDigits[i] = -val.digits[i] & ~~that.digits[i]; 405 resDigits[i] = -val.digits[i] & that.digits[i]; 406 } else { 407 // resDigits[i] = -val.digits[i] & ~-that.digits[i]; 408 resDigits[i] = -val.digits[i] & (that.digits[i] - 1); 409 } 410 411 limit = Math.min(val.numberLength, that.numberLength); 412 for (i++; i < limit; i++) { 413 // resDigits[i] = ~val.digits[i] & ~~that.digits[i]; 414 resDigits[i] = ~val.digits[i] & that.digits[i]; 415 } 416 for ( ; i < that.numberLength; i++) { 417 // resDigits[i] = -1 & ~~that.digits[i]; 418 resDigits[i] = that.digits[i]; 419 } 420 421 return new BigInteger(1, resLength, resDigits); 422 } 423 424 /** @see BigInteger#or(BigInteger) */ 425 static BigInteger or(BigInteger val, BigInteger that) { 426 if (that.equals(BigInteger.MINUS_ONE) || val.equals(BigInteger.MINUS_ONE)) { 427 return BigInteger.MINUS_ONE; 428 } 429 if (that.sign == 0) { 430 return val; 431 } 432 if (val.sign == 0) { 433 return that; 434 } 435 436 if (val.sign > 0) { 437 if (that.sign > 0) { 438 if (val.numberLength > that.numberLength) { 439 return orPositive(val, that); 440 } else { 441 return orPositive(that, val); 442 } 443 } else { 444 return orDiffSigns(val, that); 445 } 446 } else { 447 if (that.sign > 0) { 448 return orDiffSigns(that, val); 449 } else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) { 450 return orNegative(that, val); 451 } else { 452 return orNegative(val, that); 453 } 454 } 455 } 456 457 /** @return sign = 1, magnitude = longer.magnitude | shorter.magnitude*/ 458 static BigInteger orPositive(BigInteger longer, BigInteger shorter) { 459 // PRE: longer and shorter are positive; 460 // PRE: longer has at least as many digits as shorter 461 int resLength = longer.numberLength; 462 int[] resDigits = new int[resLength]; 463 464 int i; 465 for (i = 0; i < shorter.numberLength; i++) { 466 resDigits[i] = longer.digits[i] | shorter.digits[i]; 467 } 468 for ( ; i < resLength; i++) { 469 resDigits[i] = longer.digits[i]; 470 } 471 472 return new BigInteger(1, resLength, resDigits); 473 } 474 475 /** @return sign = -1, magnitude = -(-val.magnitude | -that.magnitude) */ 476 static BigInteger orNegative(BigInteger val, BigInteger that){ 477 // PRE: val and that are negative; 478 // PRE: val has at least as many trailing zeros digits as that 479 int iThat = that.getFirstNonzeroDigit(); 480 int iVal = val.getFirstNonzeroDigit(); 481 int i; 482 483 if (iVal >= that.numberLength) { 484 return that; 485 }else if (iThat >= val.numberLength) { 486 return val; 487 } 488 489 int resLength = Math.min(val.numberLength, that.numberLength); 490 int[] resDigits = new int[resLength]; 491 492 //Looking for the first non-zero digit of the result 493 if (iThat == iVal) { 494 resDigits[iVal] = -(-val.digits[iVal] | -that.digits[iVal]); 495 i = iVal; 496 } else { 497 for (i = iThat; i < iVal; i++) { 498 resDigits[i] = that.digits[i]; 499 } 500 resDigits[i] = that.digits[i] & (val.digits[i] - 1); 501 } 502 503 for (i++; i < resLength; i++) { 504 resDigits[i] = val.digits[i] & that.digits[i]; 505 } 506 507 return new BigInteger(-1, resLength, resDigits); 508 } 509 510 /** @return sign = -1, magnitude = -(positive.magnitude | -negative.magnitude) */ 511 static BigInteger orDiffSigns(BigInteger positive, BigInteger negative){ 512 // Jumping over the least significant zero bits 513 int iNeg = negative.getFirstNonzeroDigit(); 514 int iPos = positive.getFirstNonzeroDigit(); 515 int i; 516 int limit; 517 518 // Look if the trailing zeros of the positive will "copy" all 519 // the negative digits 520 if (iPos >= negative.numberLength) { 521 return negative; 522 } 523 int resLength = negative.numberLength; 524 int[] resDigits = new int[resLength]; 525 526 if (iNeg < iPos ) { 527 // We know for sure that this will 528 // be the first non zero digit in the result 529 for (i = iNeg; i < iPos; i++) { 530 resDigits[i] = negative.digits[i]; 531 } 532 } else if (iPos < iNeg) { 533 i = iPos; 534 resDigits[i] = -positive.digits[i]; 535 limit = Math.min(positive.numberLength, iNeg); 536 for (i++; i < limit; i++ ) { 537 resDigits[i] = ~positive.digits[i]; 538 } 539 if (i != positive.numberLength) { 540 resDigits[i] = ~(-negative.digits[i] | positive.digits[i]); 541 } else{ 542 for (; i<iNeg; i++) { 543 resDigits[i] = -1; 544 } 545 // resDigits[i] = ~(-negative.digits[i] | 0); 546 resDigits[i] = negative.digits[i] - 1; 547 } 548 i++; 549 } else {// iNeg == iPos 550 // Applying two complement to negative and to result 551 i = iPos; 552 resDigits[i] = -(-negative.digits[i] | positive.digits[i]); 553 i++; 554 } 555 limit = Math.min(negative.numberLength, positive.numberLength); 556 for (; i < limit; i++) { 557 // Applying two complement to negative and to result 558 // resDigits[i] = ~(~negative.digits[i] | positive.digits[i] ); 559 resDigits[i] = negative.digits[i] & ~positive.digits[i]; 560 } 561 for ( ; i < negative.numberLength; i++) { 562 resDigits[i] = negative.digits[i]; 563 } 564 565 return new BigInteger(-1, resLength, resDigits); 566 } 567 568 /** @see BigInteger#xor(BigInteger) */ 569 static BigInteger xor(BigInteger val, BigInteger that) { 570 if (that.sign == 0) { 571 return val; 572 } 573 if (val.sign == 0) { 574 return that; 575 } 576 if (that.equals(BigInteger.MINUS_ONE)) { 577 return val.not(); 578 } 579 if (val.equals(BigInteger.MINUS_ONE)) { 580 return that.not(); 581 } 582 583 if (val.sign > 0) { 584 if (that.sign > 0) { 585 if (val.numberLength > that.numberLength) { 586 return xorPositive(val, that); 587 } else { 588 return xorPositive(that, val); 589 } 590 } else { 591 return xorDiffSigns(val, that); 592 } 593 } else { 594 if (that.sign > 0) { 595 return xorDiffSigns(that, val); 596 } else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) { 597 return xorNegative(that, val); 598 } else { 599 return xorNegative(val, that); 600 } 601 } 602 } 603 604 /** @return sign = 0, magnitude = longer.magnitude | shorter.magnitude */ 605 static BigInteger xorPositive(BigInteger longer, BigInteger shorter) { 606 // PRE: longer and shorter are positive; 607 // PRE: longer has at least as many digits as shorter 608 int resLength = longer.numberLength; 609 int[] resDigits = new int[resLength]; 610 int i = Math.min(longer.getFirstNonzeroDigit(), shorter.getFirstNonzeroDigit()); 611 for ( ; i < shorter.numberLength; i++) { 612 resDigits[i] = longer.digits[i] ^ shorter.digits[i]; 613 } 614 for ( ; i < longer.numberLength; i++ ){ 615 resDigits[i] = longer.digits[i]; 616 } 617 618 return new BigInteger(1, resLength, resDigits); 619 } 620 621 /** @return sign = 0, magnitude = -val.magnitude ^ -that.magnitude */ 622 static BigInteger xorNegative(BigInteger val, BigInteger that){ 623 // PRE: val and that are negative 624 // PRE: val has at least as many trailing zero digits as that 625 int resLength = Math.max(val.numberLength, that.numberLength); 626 int[] resDigits = new int[resLength]; 627 int iVal = val.getFirstNonzeroDigit(); 628 int iThat = that.getFirstNonzeroDigit(); 629 int i = iThat; 630 int limit; 631 632 633 if (iVal == iThat) { 634 resDigits[i] = -val.digits[i] ^ -that.digits[i]; 635 } else { 636 resDigits[i] = -that.digits[i]; 637 limit = Math.min(that.numberLength, iVal); 638 for (i++; i < limit; i++) { 639 resDigits[i] = ~that.digits[i]; 640 } 641 // Remains digits in that? 642 if (i == that.numberLength) { 643 //Jumping over the remaining zero to the first non one 644 for ( ;i < iVal; i++) { 645 //resDigits[i] = 0 ^ -1; 646 resDigits[i] = -1; 647 } 648 //resDigits[i] = -val.digits[i] ^ -1; 649 resDigits[i] = val.digits[i] - 1; 650 } else { 651 resDigits[i] = -val.digits[i] ^ ~that.digits[i]; 652 } 653 } 654 655 limit = Math.min(val.numberLength, that.numberLength); 656 //Perform ^ between that al val until that ends 657 for (i++; i < limit; i++) { 658 //resDigits[i] = ~val.digits[i] ^ ~that.digits[i]; 659 resDigits[i] = val.digits[i] ^ that.digits[i]; 660 } 661 //Perform ^ between val digits and -1 until val ends 662 for ( ; i < val.numberLength; i++) { 663 //resDigits[i] = ~val.digits[i] ^ -1 ; 664 resDigits[i] = val.digits[i] ; 665 } 666 for ( ; i < that.numberLength; i++) { 667 //resDigits[i] = -1 ^ ~that.digits[i] ; 668 resDigits[i] = that.digits[i]; 669 } 670 671 return new BigInteger(1, resLength, resDigits); 672 } 673 674 /** @return sign = 1, magnitude = -(positive.magnitude ^ -negative.magnitude)*/ 675 static BigInteger xorDiffSigns(BigInteger positive, BigInteger negative){ 676 int resLength = Math.max(negative.numberLength, positive.numberLength); 677 int[] resDigits; 678 int iNeg = negative.getFirstNonzeroDigit(); 679 int iPos = positive.getFirstNonzeroDigit(); 680 int i; 681 int limit; 682 683 //The first 684 if (iNeg < iPos) { 685 resDigits = new int[resLength]; 686 i = iNeg; 687 //resDigits[i] = -(-negative.digits[i]); 688 resDigits[i] = negative.digits[i]; 689 limit = Math.min(negative.numberLength, iPos); 690 //Skip the positive digits while they are zeros 691 for (i++; i < limit; i++) { 692 //resDigits[i] = ~(~negative.digits[i]); 693 resDigits[i] = negative.digits[i]; 694 } 695 //if the negative has no more elements, must fill the 696 //result with the remaining digits of the positive 697 if (i == negative.numberLength) { 698 for ( ; i < positive.numberLength; i++) { 699 //resDigits[i] = ~(positive.digits[i] ^ -1) -> ~(~positive.digits[i]) 700 resDigits[i] = positive.digits[i]; 701 } 702 } 703 } else if (iPos < iNeg) { 704 resDigits = new int[resLength]; 705 i = iPos; 706 //Applying two complement to the first non-zero digit of the result 707 resDigits[i] = -positive.digits[i]; 708 limit = Math.min(positive.numberLength, iNeg); 709 for (i++; i < limit; i++) { 710 //Continue applying two complement the result 711 resDigits[i] = ~positive.digits[i]; 712 } 713 //When the first non-zero digit of the negative is reached, must apply 714 //two complement (arithmetic negation) to it, and then operate 715 if (i == iNeg) { 716 resDigits[i] = ~(positive.digits[i] ^ -negative.digits[i]); 717 i++; 718 } else { 719 //if the positive has no more elements must fill the remaining digits with 720 //the negative ones 721 for ( ; i < iNeg; i++) { 722 // resDigits[i] = ~(0 ^ 0) 723 resDigits[i] = -1; 724 } 725 for ( ; i < negative.numberLength; i++) { 726 //resDigits[i] = ~(~negative.digits[i] ^ 0) 727 resDigits[i] = negative.digits[i]; 728 } 729 } 730 } else { 731 //The first non-zero digit of the positive and negative are the same 732 i = iNeg; 733 int digit = positive.digits[i] ^ -negative.digits[i]; 734 if (digit == 0) { 735 limit = Math.min(positive.numberLength, negative.numberLength); 736 for (i++; i < limit && (digit = positive.digits[i] ^ ~negative.digits[i]) == 0; i++) 737 ; 738 if (digit == 0) { 739 // shorter has only the remaining virtual sign bits 740 for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++) 741 ; 742 for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++) 743 ; 744 if (digit == 0) { 745 resLength = resLength + 1; 746 resDigits = new int[resLength]; 747 resDigits[resLength - 1] = 1; 748 749 return new BigInteger(-1, resLength, resDigits); 750 } 751 } 752 } 753 resDigits = new int[resLength]; 754 resDigits[i] = -digit; 755 i++; 756 } 757 758 limit = Math.min(negative.numberLength, positive.numberLength); 759 for ( ; i < limit; i++) { 760 resDigits[i] = ~(~negative.digits[i] ^ positive.digits[i]); 761 } 762 for ( ; i < positive.numberLength; i++) { 763 // resDigits[i] = ~(positive.digits[i] ^ -1) 764 resDigits[i] = positive.digits[i]; 765 } 766 for ( ; i < negative.numberLength; i++) { 767 // resDigits[i] = ~(0 ^ ~negative.digits[i]) 768 resDigits[i] = negative.digits[i]; 769 } 770 771 return new BigInteger(-1, resLength, resDigits); 772 } 773} 774