/android/upstream/java/math/Logical.java

https://bitbucket.org/festevezga/xobotos · Java · 773 lines · 565 code · 74 blank · 134 comment · 213 complexity · 149f2ed0fa5232d1246ca68ffc415f16 MD5 · raw file

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