PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/WOGWT-Emulation/src/wogwt/emulation/java/math/Logical.java

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