BitOps.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. // Copyright (c) 1997 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.math;
  4. /** Implements logical (bit-wise) operations on infinite-precision integers.
  5. * There are no BitOps object - all the functions here are static.
  6. * The semantics used are the same as for Common Lisp.
  7. * @author Per Bothner
  8. */
  9. public class BitOps
  10. {
  11. private BitOps () { }
  12. /** Return the value of a specified bit in an IntNum. */
  13. public static boolean bitValue (IntNum x, int bitno)
  14. {
  15. int i = x.ival;
  16. if (x.words == null)
  17. {
  18. return bitno >= 32 ? i < 0 : ((i >> bitno) & 1) != 0;
  19. }
  20. else
  21. {
  22. int wordno = bitno >> 5;
  23. return wordno >= i ? x.words[i-1] < 0
  24. : ((x.words[wordno] >> bitno) & 1) != 0;
  25. }
  26. }
  27. /** Make a fresh buffer conatining the value of x.
  28. * Make sure bitno ius within the buffer.
  29. */
  30. static int [] dataBufferFor (IntNum x, int bitno)
  31. {
  32. int i = x.ival;
  33. int[] data;
  34. int nwords = (bitno+1) >> 5;
  35. if (x.words == null)
  36. {
  37. if (nwords == 0)
  38. nwords = 1;
  39. data = new int[nwords];
  40. data[0] = i;
  41. if (i < 0) // Sign-extend if needed.
  42. {
  43. for (int j = 1; j < nwords; j++)
  44. data[j] = -1;
  45. }
  46. }
  47. else
  48. {
  49. nwords = (bitno+1) >> 5;
  50. data = new int[nwords > i ? nwords : i];
  51. for (int j = i; --j >= 0; )
  52. data[j] = x.words[j];
  53. if (data[i-1] < 0) // Sign-extend if needed.
  54. {
  55. for (int j = i; j < nwords; j++)
  56. data[j] = -1;
  57. }
  58. }
  59. return data;
  60. }
  61. /** Set the value of a specified bit in an IntNum. */
  62. public static IntNum setBitValue (IntNum x, int bitno, int newValue)
  63. {
  64. newValue &= 1;
  65. int i = x.ival;
  66. int[] data;
  67. int nwords;
  68. if (x.words == null)
  69. {
  70. int oldValue = (i >> (bitno < 31 ? bitno : 31)) & 1;
  71. if (oldValue == newValue)
  72. return x;
  73. if (bitno < 63)
  74. return IntNum.make((long) i ^ (long) (1 << bitno));
  75. }
  76. else
  77. {
  78. int wordno = bitno >> 5;
  79. int oldValue;
  80. if (wordno >= i)
  81. oldValue = x.words[i-1] < 0 ? 1 : 0;
  82. else
  83. oldValue = (x.words[wordno] >> bitno) & 1;
  84. if (oldValue == newValue)
  85. return x;
  86. }
  87. data = dataBufferFor(x, bitno);
  88. data[bitno >> 5] ^= 1 << (bitno & 31);
  89. return IntNum.make(data, data.length);
  90. }
  91. /** Return true iff an IntNum and an int have any true bits in common. */
  92. public static boolean test (IntNum x, int y)
  93. {
  94. if (x.words == null)
  95. return (x.ival & y) != 0;
  96. return (y < 0) || (x.words[0] & y) != 0;
  97. }
  98. /** Return true iff two IntNums have any true bits in common. */
  99. public static boolean test (IntNum x, IntNum y)
  100. {
  101. if (y.words == null)
  102. return test (x, y.ival);
  103. else if (x.words == null)
  104. return test (y, x.ival);
  105. if (x.ival < y.ival)
  106. {
  107. IntNum temp = x; x = y; y = temp;
  108. }
  109. for (int i = 0; i < y.ival; i++)
  110. {
  111. if ((x.words[i] & y.words[i]) != 0)
  112. return true;
  113. }
  114. return y.isNegative ();
  115. }
  116. /** Return the logical (bit-wise) "and" of an IntNum and an int. */
  117. public static IntNum and (IntNum x, int y)
  118. {
  119. if (x.words == null)
  120. return IntNum.make (x.ival & y);
  121. if (y >= 0)
  122. return IntNum.make (x.words[0] & y);
  123. int len = x.ival;
  124. int[] words = new int[len];
  125. words[0] = x.words[0] & y;
  126. while (--len > 0)
  127. words[len] = x.words[len];
  128. return IntNum.make (words, x.ival);
  129. }
  130. /** Return the logical (bit-wise) "and" of two IntNums. */
  131. public static IntNum and (IntNum x, IntNum y)
  132. {
  133. if (y.words == null)
  134. return and (x, y.ival);
  135. else if (x.words == null)
  136. return and (y, x.ival);
  137. if (x.ival < y.ival)
  138. {
  139. IntNum temp = x; x = y; y = temp;
  140. }
  141. int i;
  142. int len = y.isNegative () ? x.ival : y.ival;
  143. int[] words = new int[len];
  144. for (i = 0; i < y.ival; i++)
  145. words[i] = x.words[i] & y.words[i];
  146. for ( ; i < len; i++)
  147. words[i] = x.words[i];
  148. return IntNum.make (words, len);
  149. }
  150. /** Return the logical (bit-wise) "(inclusive) or" of two IntNums. */
  151. public static IntNum ior (IntNum x, IntNum y)
  152. {
  153. return bitOp (7, x, y);
  154. }
  155. /** Return the logical (bit-wise) "exclusive or" of two IntNums. */
  156. public static IntNum xor (IntNum x, IntNum y)
  157. {
  158. return bitOp (6, x, y);
  159. }
  160. /** Return the logical (bit-wise) negation of an IntNum. */
  161. public static IntNum not (IntNum x)
  162. {
  163. return bitOp (12, x, IntNum.zero ());
  164. }
  165. /** Return the boolean opcode (for bitOp) for swapped operands.
  166. * I.e. bitOp (swappedOp(op), x, y) == bitOp (op, y, x).
  167. */
  168. public static int swappedOp (int op)
  169. {
  170. return
  171. "\000\001\004\005\002\003\006\007\010\011\014\015\012\013\016\017"
  172. .charAt (op);
  173. }
  174. /** Do one the the 16 possible bit-wise operations of two IntNums. */
  175. public static IntNum bitOp (int op, IntNum x, IntNum y)
  176. {
  177. switch (op)
  178. {
  179. case 0: return IntNum.zero();
  180. case 1: return and (x, y);
  181. case 3: return x;
  182. case 5: return y;
  183. case 15: return IntNum.minusOne();
  184. }
  185. IntNum result = new IntNum ();
  186. setBitOp (result, op, x, y);
  187. return result.canonicalize ();
  188. }
  189. /** Do one the the 16 possible bit-wise operations of two IntNums. */
  190. public static void setBitOp (IntNum result, int op, IntNum x, IntNum y)
  191. {
  192. if (y.words == null) ;
  193. else if (x.words == null || x.ival < y.ival)
  194. {
  195. IntNum temp = x; x = y; y = temp;
  196. op = swappedOp (op);
  197. }
  198. int xi;
  199. int yi;
  200. int xlen, ylen;
  201. if (y.words == null)
  202. {
  203. yi = y.ival;
  204. ylen = 1;
  205. }
  206. else
  207. {
  208. yi = y.words[0];
  209. ylen = y.ival;
  210. }
  211. if (x.words == null)
  212. {
  213. xi = x.ival;
  214. xlen = 1;
  215. }
  216. else
  217. {
  218. xi = x.words[0];
  219. xlen = x.ival;
  220. }
  221. if (xlen > 1)
  222. result.realloc (xlen);
  223. int[] w = result.words;
  224. int i = 0;
  225. // Code for how to handle the remainder of x.
  226. // 0: Truncate to length of y.
  227. // 1: Copy rest of x.
  228. // 2: Invert rest of x.
  229. int finish = 0;
  230. int ni;
  231. switch (op)
  232. {
  233. case 0: // clr
  234. ni = 0;
  235. break;
  236. case 1: // and
  237. for (;;)
  238. {
  239. ni = xi & yi;
  240. if (i+1 >= ylen) break;
  241. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  242. }
  243. if (yi < 0) finish = 1;
  244. break;
  245. case 2: // andc2
  246. for (;;)
  247. {
  248. ni = xi & ~yi;
  249. if (i+1 >= ylen) break;
  250. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  251. }
  252. if (yi >= 0) finish = 1;
  253. break;
  254. case 3: // copy x
  255. ni = xi;
  256. finish = 1; // Copy rest
  257. break;
  258. case 4: // andc1
  259. for (;;)
  260. {
  261. ni = ~xi & yi;
  262. if (i+1 >= ylen) break;
  263. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  264. }
  265. if (yi < 0) finish = 2;
  266. break;
  267. case 5: // copy y
  268. for (;;)
  269. {
  270. ni = yi;
  271. if (i+1 >= ylen) break;
  272. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  273. }
  274. break;
  275. case 6: // xor
  276. for (;;)
  277. {
  278. ni = xi ^ yi;
  279. if (i+1 >= ylen) break;
  280. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  281. }
  282. finish = yi < 0 ? 2 : 1;
  283. break;
  284. case 7: // ior
  285. for (;;)
  286. {
  287. ni = xi | yi;
  288. if (i+1 >= ylen) break;
  289. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  290. }
  291. if (yi >= 0) finish = 1;
  292. break;
  293. case 8: // nor
  294. for (;;)
  295. {
  296. ni = ~(xi | yi);
  297. if (i+1 >= ylen) break;
  298. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  299. }
  300. if (yi >= 0) finish = 2;
  301. break;
  302. case 9: // eqv [exclusive nor]
  303. for (;;)
  304. {
  305. ni = ~(xi ^ yi);
  306. if (i+1 >= ylen) break;
  307. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  308. }
  309. finish = yi >= 0 ? 2 : 1;
  310. break;
  311. case 10: // c2
  312. for (;;)
  313. {
  314. ni = ~yi;
  315. if (i+1 >= ylen) break;
  316. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  317. }
  318. break;
  319. case 11: // orc2
  320. for (;;)
  321. {
  322. ni = xi | ~yi;
  323. if (i+1 >= ylen) break;
  324. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  325. }
  326. if (yi < 0) finish = 1;
  327. break;
  328. case 12: // c1
  329. ni = ~xi;
  330. finish = 2;
  331. break;
  332. case 13: // orc1
  333. for (;;)
  334. {
  335. ni = ~xi | yi;
  336. if (i+1 >= ylen) break;
  337. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  338. }
  339. if (yi >= 0) finish = 2;
  340. break;
  341. case 14: // nand
  342. for (;;)
  343. {
  344. ni = ~(xi & yi);
  345. if (i+1 >= ylen) break;
  346. w[i++] = ni; xi = x.words[i]; yi = y.words[i];
  347. }
  348. if (yi < 0) finish = 2;
  349. break;
  350. default:
  351. case 15: // set
  352. ni = -1;
  353. break;
  354. }
  355. // Here i==ylen-1; w[0]..w[i-1] have the correct result;
  356. // and ni contains the correct result for w[i+1].
  357. if (i+1 == xlen)
  358. finish = 0;
  359. switch (finish)
  360. {
  361. case 0:
  362. if (i == 0 && w == null)
  363. {
  364. result.ival = ni;
  365. return;
  366. }
  367. w[i++] = ni;
  368. break;
  369. case 1: w[i] = ni; while (++i < xlen) w[i] = x.words[i]; break;
  370. case 2: w[i] = ni; while (++i < xlen) w[i] = ~x.words[i]; break;
  371. }
  372. result.ival = i;
  373. }
  374. /** Create a mask with bits true form bits form startBit to endBit. */
  375. public static IntNum makeMask(int startBit, int endBit) {
  376. int width = endBit-startBit;
  377. if (width <= 0)
  378. return IntNum.zero();
  379. if (endBit < 64)
  380. return IntNum.make(~(-1L << width) << startBit);
  381. int len = (endBit >> 5) + 1;
  382. int[] buf = new int[len];
  383. int startWord = startBit >> 5;
  384. int i = width >> 5;
  385. buf[i] = ~(-1 << (width & 31));
  386. while (--i >= 0)
  387. buf[i] = -1;
  388. // Now buf contains '1' in the width low-order bits.
  389. MPN.lshift(buf, startWord, buf, len-startWord, startBit&31);
  390. for (i = startWord; --i >= 0; )
  391. buf[i] = 0;
  392. return IntNum.make(buf, len);
  393. }
  394. /** Extract a bit-field as an unsigned integer. */
  395. public static IntNum extract (IntNum x, int startBit, int endBit)
  396. {
  397. //System.err.print("extract(["); if (x.words!=null) MPN.dprint(x.words);
  398. //System.err.println (","+x.ival+"], start:"+startBit+", end:"+endBit);
  399. if (endBit < 32)
  400. {
  401. int word0 = x.words == null ? x.ival : x.words[0];
  402. return IntNum.make ((word0 & ~((-1) << endBit)) >> startBit);
  403. }
  404. int x_len;
  405. if (x.words == null)
  406. {
  407. if (x.ival >= 0)
  408. return IntNum.make (startBit >= 31 ? 0 : (x.ival >> startBit));
  409. x_len = 1;
  410. }
  411. else
  412. x_len = x.ival;
  413. boolean neg = x.isNegative ();
  414. if (endBit > 32 * x_len)
  415. {
  416. endBit = 32 * x_len;
  417. if (!neg && startBit == 0)
  418. return x;
  419. }
  420. else
  421. x_len = (endBit + 31) >> 5;
  422. int length = endBit - startBit;
  423. if (length < 64)
  424. {
  425. long l;
  426. if (x.words == null)
  427. l = x.ival >> (startBit >= 32 ? 31 : startBit);
  428. else
  429. l = MPN.rshift_long (x.words, x_len, startBit);
  430. return IntNum.make (l & ~((-1L) << length));
  431. }
  432. int startWord = startBit >> 5;
  433. // Allocate a work buffer, which has to be large enough for the result
  434. // AND large enough for all words we use from x (including possible
  435. // partial words at both ends).
  436. int buf_len = (endBit >> 5) + 1 - startWord;
  437. int[] buf = new int[buf_len];
  438. if (x.words == null) // x < 0.
  439. buf[0] = startBit >= 32 ? -1 : (x.ival >> startBit);
  440. else
  441. {
  442. x_len -= startWord;
  443. startBit &= 31;
  444. MPN.rshift0 (buf, x.words, startWord, x_len, startBit);
  445. }
  446. x_len = length >> 5;
  447. buf[x_len] &= ~((-1) << length);
  448. return IntNum.make (buf, x_len + 1);
  449. }
  450. public static int lowestBitSet (int i)
  451. {
  452. if (i == 0)
  453. return -1;
  454. int index = 0;
  455. while ((i & 0xFF) == 0)
  456. {
  457. i >>>= 8;
  458. index += 8;
  459. }
  460. while ((i & 3) == 0)
  461. {
  462. i >>>= 2;
  463. index += 2;
  464. }
  465. if ((i & 1) == 0)
  466. index++;
  467. return index;
  468. }
  469. public static int lowestBitSet (IntNum x)
  470. {
  471. int[] x_words = x.words;
  472. if (x_words == null)
  473. {
  474. return lowestBitSet(x.ival);
  475. }
  476. else
  477. {
  478. int x_len = x.ival;
  479. for (int i = 0; i < x_len; )
  480. {
  481. int b = lowestBitSet(x_words[i]);
  482. if (b >= 0)
  483. return 32 * i + b;
  484. }
  485. return -1;
  486. }
  487. }
  488. // bit4count[I] is number of '1' bits in I.
  489. static final byte[] bit4_count = { 0, 1, 1, 2, 1, 2, 2, 3,
  490. 1, 2, 2, 3, 2, 3, 3, 4};
  491. public static int bitCount (int i)
  492. {
  493. int count = 0;
  494. while (i != 0)
  495. {
  496. count += bit4_count[i & 15];
  497. i >>>= 4;
  498. }
  499. return count;
  500. }
  501. public static int bitCount (int[] x, int len)
  502. {
  503. int count = 0;
  504. while (--len >= 0)
  505. count += bitCount (x[len]);
  506. return count;
  507. }
  508. /** Count one bits in an IntNum.
  509. * If argument is negative, count zero bits instead. */
  510. public static int bitCount (IntNum x)
  511. {
  512. int i, x_len;
  513. int[] x_words = x.words;
  514. if (x_words == null)
  515. {
  516. x_len = 1;
  517. i = bitCount (x.ival);
  518. }
  519. else
  520. {
  521. x_len = x.ival;
  522. i = bitCount (x_words, x_len);
  523. }
  524. return x.isNegative () ? x_len * 32 - i : i;
  525. }
  526. public static IntNum reverseBits (IntNum x, int start, int end)
  527. {
  528. int ival = x.ival;
  529. int[] xwords = x.words;
  530. if (xwords == null)
  531. {
  532. if (end < 63)
  533. {
  534. long w = ival;
  535. int i = start;
  536. int j = end - 1;
  537. while (i < j)
  538. {
  539. long biti = (w >> i) & 1;
  540. long bitj = (w >> j) & 1;
  541. w &= ~((1L << i) | (1L << j));
  542. w = w | (biti << j) | (bitj << i);
  543. i++;
  544. j--;
  545. }
  546. return IntNum.make(w);
  547. }
  548. }
  549. int[] data = dataBufferFor(x, end-1);
  550. int i = start;
  551. int j = end - 1;
  552. while (i < j)
  553. {
  554. int ii = i >> 5;
  555. int jj = j >> 5;
  556. int wi = data[ii];
  557. int biti = (wi >> i) & 1;
  558. if (ii == jj)
  559. {
  560. int bitj = (wi >> j) & 1;
  561. wi &= ~((1L << i) | (1L << j));
  562. wi = wi | (biti << j) | (bitj << i);
  563. }
  564. else
  565. {
  566. int wj = data[jj];
  567. int bitj = (wj >> (j & 31)) & 1;
  568. wi &= ~(1 << (i & 31));
  569. wj &= ~(1 << (j & 31));
  570. wi |= bitj << (i & 31);
  571. wj |= biti << (j & 31);
  572. data[jj] = wj;
  573. }
  574. data[ii] = wi;
  575. i++;
  576. j--;
  577. }
  578. return IntNum.make(data, data.length);
  579. }
  580. public static int shift(int x, int count) {
  581. if (count >= 32)
  582. return 0;
  583. if (count >= 0)
  584. return x << count;
  585. count = -count;
  586. if (count >= 32)
  587. return x < 0 ? -1 : 0;
  588. return x >> count;
  589. }
  590. public static int shiftUnsigned(int x, int count) {
  591. if (count >= 32)
  592. return 0;
  593. if (count >= 0)
  594. return x << count;
  595. count = -count;
  596. return count >= 32 ? 0 : x >>> count;
  597. }
  598. public static long shift(long x, int count) {
  599. if (count >= 64)
  600. return 0;
  601. if (count >= 0)
  602. return x << count;
  603. count = -count;
  604. if (count >= 64)
  605. return x < 0 ? -1 : 0;
  606. return x >> count;
  607. }
  608. public static long shiftUnsigned(long x, int count) {
  609. if (count >= 64)
  610. return 0;
  611. if (count >= 0)
  612. return x << count;
  613. count = -count;
  614. return count >= 64 ? 0 : x >>> count;
  615. }
  616. }