/trunk/JavApi/java/math/Logical.cs

# · C# · 802 lines · 596 code · 74 blank · 132 comment · 213 complexity · b6bf95981ad2f0eb50f485e89837a4a0 MD5 · raw file

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