arith09.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180
  1. /* arith09.c Copyright (C) 1989-1996 Codemist Ltd */
  2. /*
  3. * Arithmetic functions.
  4. * GCD and some boolean operations
  5. *
  6. * Version 1.2 October 1992.
  7. */
  8. /* Signature: 365c3dca 07-Mar-2000 */
  9. #include <stdarg.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12. #include <math.h>
  13. #include "machine.h"
  14. #include "tags.h"
  15. #include "cslerror.h"
  16. #include "externs.h"
  17. #include "arith.h"
  18. #ifdef TIMEOUT
  19. #include "timeout.h"
  20. #endif
  21. static Lisp_Object absb(Lisp_Object a)
  22. /*
  23. * take absolute value of a bignum
  24. */
  25. {
  26. int32 len = bignum_length(a) >> 2;
  27. if ((int32)bignum_digits(a)[len-2] < 0) return negateb(a);
  28. else return a;
  29. }
  30. /*
  31. * The next two functions help with bignum GCDs
  32. */
  33. static void next_gcd_step(unsigned32 a0, unsigned32 a1,
  34. unsigned32 b0, unsigned32 b1,
  35. int32 *axp, int32 *ayp, int32 *bxp, int32*byp)
  36. /*
  37. * This function takes the two leading digits (a0,a1) and (b0,b1) of
  38. * a pair of numbers A and B and performs an extended GCD process to
  39. * find values ax, bx, ay and by with a view to letting
  40. * A' = ax*A + ay*B
  41. * B' = bx*A + by*B
  42. * and gcd(A', B') will be the same as gcd(A, B), but A' and B' will
  43. * be smaller than A and B by a factor of (up to, about) 2^30. On entry
  44. * A must be at least as big as B and B must be nonzero. If A/B is
  45. * bigger than about 0x40000000 the code will return early without doing
  46. * much - this must be detected and handled by the caller. The case where
  47. * no progress has been made will be signalled because the values ax, ay,
  48. * bx and by will be returned as ((1, 0), (0, 1)). Note that through the
  49. * body of this code axy and bxy hold ax+ay and bx+by
  50. */
  51. {
  52. int32 ax = 1, axy = 1,
  53. bx = 0, bxy = 1;
  54. unsigned32 q;
  55. int n = 0;
  56. /*
  57. * I will keep A and B as double-precision values with a view to getting
  58. * the most progress out of this that I can. Also I round B up, so that
  59. * the quotient (A/B) is guaranteed to be an under-estimate for the true
  60. * result. Note that A was rounded down just by the process of keeping
  61. * only the two leading digits.
  62. */
  63. b1++;
  64. if ((int32)b1 < 0)
  65. { b0++;
  66. b1 = 0; /* carry if necessary */
  67. }
  68. /*
  69. * If b0 overflowed here then both A and B must have started off as
  70. * 0x7fffffff:0x7fffffff (since B was like that to overflow when incremented,
  71. * and A>=B). I return as if this code was invalid, and the fall-back
  72. * case will do one step and tidy up a bit. A jolly uncommon case!
  73. */
  74. if ((int)b0 >= 0)
  75. { for (;;)
  76. { unsigned32 c0, c1;
  77. /*
  78. * If A/B would overflow I break. This includes the special case where B
  79. * has reduced to zero. I compute q = (a0,a1)/(b0,b1)
  80. */
  81. if (b0 == 0)
  82. { unsigned32 qt;
  83. if (a0 >= b1) break; /* Overflow exit */
  84. Ddivide(a1, qt, a0, a1, b1);
  85. a0 = 0; /* Leave the remainder in A */
  86. q = qt; /* Accurate quotient here */
  87. }
  88. else
  89. /*
  90. * I expect that the quotient here will be quite small, so I compute it in
  91. * a way optimised for such cases. This is just a simple shift-and-subtract
  92. * bit of division code, but for small quotients the number of loops executed
  93. * will be small. This naturally leaves the remainder in A.
  94. */
  95. { unsigned32 qt = 1;
  96. q = 0;
  97. /*
  98. * This code uses B (it shifts it left a few bits to start with) but at the
  99. * end B has been put back in its original state.
  100. */
  101. while (b0 < a0) /* Shift B left until >= A */
  102. { b0 = b0 << 1;
  103. b1 = b1 << 1;
  104. if ((int32)b1 < 0)
  105. { b0++;
  106. b1 &= 0x7fffffff;
  107. }
  108. qt = qt << 1; /* qt marks a bit position */
  109. }
  110. for (;;) /* Shift/subtract loop to get quotient */
  111. { if (b0 < a0 ||
  112. (b0 == a0 && b1 <= a1))
  113. { q |= qt;
  114. a0 -= b0;
  115. a1 -= b1;
  116. if ((int32)a1 < 0)
  117. { a0--;
  118. a1 &= 0x7fffffff;
  119. }
  120. }
  121. qt = qt >> 1;
  122. if (qt == 0) break;
  123. b1 = b1 >> 1;
  124. if ((b0 & 1) != 0) b1 |= 0x40000000;
  125. b0 = b0 >> 1;
  126. }
  127. }
  128. /*
  129. * Now A hold the next remainder onwards, so flip A and B
  130. */
  131. c0 = a0; c1 = a1; a0 = b0; a1 = b1; b0 = c0; b1 = c1;
  132. /*
  133. * If either of the next re-calculations of bx, bxy overflow then I ought
  134. * to exit before updating ax, bx, axy and bxy. Things are arranged so that
  135. * all values remain positive at this stage.
  136. */
  137. { unsigned32 cx, cxy;
  138. Dmultiply(cx, cxy, bxy, q, axy);
  139. if (cx != 0) break;
  140. /*
  141. * cxy will be >= cx, so if cxy did not overflow then cx can not. Thus it
  142. * is safe to use regular (not double-length) multiplication here.
  143. */
  144. cx = bx*q + ax;
  145. axy = bxy; bxy = cxy;
  146. ax = bx; bx = cx;
  147. n++;
  148. }
  149. /*
  150. * I update A and B in such a way that they alternate between the
  151. * sequences for under- and over-estimates of the true ratio. This is done
  152. * so that the partial quotients I compute always tend to be underestimates.
  153. */
  154. a1 = a1 - axy;
  155. if ((int32)a1 < 0)
  156. { a1 &= 0x7fffffff;
  157. a0--;
  158. }
  159. b1 = b1 + bxy;
  160. if ((int32)b1 < 0)
  161. { b1 &= 0x7fffffff;
  162. b0++;
  163. }
  164. if (b0 > a0 ||
  165. (b0 == a0 && b1 >= a1)) break;
  166. }
  167. } /* This is the end of the block testing the initial quotient */
  168. { int32 ay = axy - ax,
  169. by = bxy - bx;
  170. /*
  171. * Use of this route would involve computing A*x+B*y and C*x+D*y,
  172. * which is 4 multiplications. Simple division would be just A-q*B at
  173. * one division. To account for this I pretend that I made no progress
  174. * at all if I would simulate less than 3 regular remainder steps. This is
  175. * 3 rather than 4 because (maybe) the Lehmer code bundles up more work for
  176. * the overhead that it spends.
  177. */
  178. if (n < 3) ax = 1, ay = 0, bx = 0, by = 1;
  179. else if ((n & 1) != 0)
  180. { ax = -ax;
  181. by = -by;
  182. }
  183. else
  184. { ay = -ay;
  185. bx = -bx;
  186. }
  187. /*
  188. * Copy results into the places where they are wanted.
  189. */
  190. *axp = ax;
  191. *ayp = ay;
  192. *bxp = bx;
  193. *byp = by;
  194. return;
  195. }
  196. }
  197. static int32 huge_gcd(unsigned32 *a, int32 lena, unsigned32 *b, int32 lenb)
  198. /*
  199. * A and B are vectors of unsigned integers, representing numbers with
  200. * radix 2^31. lena and lenb indicate how many digits are present. The
  201. * numbers are unsigned. This will use the vectors as workspace and
  202. * compute the GCD of the two integers. The result handed back will
  203. * really consist of two parts. The first is a flag (held in the top
  204. * bit) that indicates whether A and B were swopped. The remaining bits
  205. * hold the length (remaining) of A.
  206. */
  207. {
  208. unsigned32 a0, a1, a2, b0, b1;
  209. int flipped = 0;
  210. /*
  211. * The next two lines adjust for an oddity in my bignum representation - the
  212. * if the leading digit would have its 0x40000000 bit set then I stick on
  213. * a leading zero. This gives me a bit more in hand wrt signed values.
  214. */
  215. if (a[lena] == 0) lena--;
  216. if (b[lenb] == 0) lenb--;
  217. for (;;)
  218. {
  219. unsigned32 q;
  220. int32 lenr;
  221. /*
  222. * I will perform reductions until the smaller of my two bignums has been
  223. * reduced to a single-precision value. After that the tidying up to
  224. * obtain the true GCD will be fairly easy.
  225. * If one number is MUCH bigger than the other I will do (part of) a
  226. * regular remainder calculation to reduce it. If the two numbers are
  227. * about the same size then I will combine several big-number operations
  228. * into one - the clever part of this entire program.
  229. */
  230. if (lena < lenb)
  231. { unsigned32 *c = a;
  232. int32 lenc = lena;
  233. a = b; lena = lenb;
  234. b = c; lenb = lenc;
  235. flipped ^= 1;
  236. }
  237. if (lenb == 0) break; /* B (at least) is now single precision */
  238. else if (lena == lenb)
  239. { while (lenb >= 0 && a[lenb] == b[lenb]) lenb--;
  240. /*
  241. * Here I want to ensure that A is really at least as big as B. While
  242. * so doing I may happen to discover that they are actually the same value.
  243. * If I do that I set things so that B looks like a single precision zero
  244. * and exit from the loop. The result will be that A gets returned as the
  245. * GCD.
  246. */
  247. if (lenb < 0)
  248. { b[0] = 0;
  249. lenb = 0;
  250. break;
  251. }
  252. if (a[lenb] < b[lenb])
  253. { unsigned32 *c = a; /* NB do not swop lena, lenb here */
  254. a = b; /* since lenb has been used as scratch */
  255. b = c; /* and both numbers are lena long */
  256. flipped ^= 1;
  257. }
  258. /*
  259. * Since the shorter number was double-length (at least) it is OK to
  260. * grab the first two digits of each.
  261. */
  262. a0 = a[lena]; a1 = a[lena-1];
  263. b0 = b[lena]; b1 = b[lena-1];
  264. lenb = lena;
  265. goto lehmer;
  266. }
  267. else if (lena == lenb+1)
  268. { a0 = a[lena]; a1 = a[lenb];
  269. b0 = 0; b1 = b[lenb];
  270. /*
  271. * If one number has one more digit than the other but the quotient will
  272. * still be small I may be able to use the Lehmer code.
  273. */
  274. if (a0 < b1) goto lehmer;
  275. }
  276. /*
  277. * Here I need to do one step towards reduction by division. A is
  278. * at leat as long as B, and B has at least two digits.
  279. */
  280. reduce_by_division:
  281. a0 = a[lena]; a1 = a[lena-1];
  282. b0 = b[lenb]; b1 = b[lenb-1];
  283. if (lena > 1) a2 = a[lena-2];
  284. else a2 = 0;
  285. /*
  286. * Now I intend to estimate A/B by computing (a0,a1,a2)/(b0,b1). To do
  287. * this I will first shift the leading digits of A and B right until b0
  288. * vanishes, then I will just need to compute (a0,a1,a2)/b1. If this
  289. * would overflow, I compute (a0,a1)/b1 instead.
  290. */
  291. while (b0 != 0)
  292. { b1 = b1 >> 1;
  293. if ((b0 & 1) != 0) b1 |= 0x40000000;
  294. b0 = b0 >> 1;
  295. a2 = a2 >> 1;
  296. if ((a1 & 1) != 0) a2 |= 0x40000000;
  297. a1 = a1 >> 1;
  298. if ((a0 & 1) != 0) a1 |= 0x40000000;
  299. a0 = a0 >> 1;
  300. }
  301. lenr = lena;
  302. if (b1 == 0x7fffffff)
  303. /*
  304. * I make b1 = 0x7fffffff a special case because (a) then B is as well-
  305. * normalised as it possibly can be and so maybe my estimated quotient
  306. * should be quite accurate and (b) I want to ensure that the estimate
  307. * for q that I obtain here is an UNDER-estimate (if anything), and I
  308. * will achieve this by knowing that A has been rounded down a bit and by
  309. * rounding B up. This rounding will mean that in general each reduction
  310. * step here will be able to remove 29 or 30 bits from the difference
  311. * between the lengths of A and B. I hope that getting q more accurate
  312. * would not justify the extra effort. My worry is that regard is that
  313. * maybe a couple of bits of error on one step will over-often lead to
  314. * the very next q having to be just 1 or 2 in value, which would represent
  315. * not very much progress in the step. My main justification for taking
  316. * a relaxed view is that except for the very first step in the remainder
  317. * sequence it will be very uncommon for this code to be activated.
  318. */
  319. { if (a0 != 0) q = a0;
  320. else if (lena == lenb) q = 1;
  321. else q = a1, lenr--;
  322. }
  323. else
  324. { unsigned32 rtemp, qtemp;
  325. b1++; /* To achieve rounding down of q */
  326. if (a0 != 0 || a1 >= b1) Ddivide(rtemp, qtemp, a0, a1, b1);
  327. /*
  328. * The following line indicates a special case needed when this division
  329. * is almost done - up to almost the end I can afford to approximate a
  330. * true quotient (1,0,...) as (0,ffffffff,...), but eventually I must
  331. * grit my teeth and get things right. Since I have carefully tested and
  332. * ensured that A>B I KNOW that the true quotient is at least 1, so when
  333. * lena==lenb I can force this is if I was in danger of estimating a lower
  334. * value.
  335. */
  336. else if (lena == lenb) qtemp = 1;
  337. else { Ddivide(rtemp, qtemp, a1, a2, b1); lenr--; }
  338. q = qtemp;
  339. }
  340. /*
  341. * Now q is an approximation to the leading digit of the quotient.
  342. * I now want to replace a by a - q*b*r^(lenr-lenb).
  343. */
  344. { unsigned32 carry = 0, carry1 = 1;
  345. int32 i, j;
  346. for (i=0, j=lenr-lenb; i<=lenb; i++, j++)
  347. { unsigned32 mlow, w;
  348. Dmultiply(carry, mlow, b[i], q, carry);
  349. w = a[j] + clear_top_bit(~mlow) + carry1;
  350. if ((int32)w < 0)
  351. { w = clear_top_bit(w);
  352. carry1 = 1;
  353. }
  354. else carry1 = 0;
  355. a[j] = w;
  356. }
  357. a[j] = a[j] + (~carry) + carry1;
  358. }
  359. while (lena > 0 && a[lena]==0) lena--;
  360. continue;
  361. lehmer:
  362. { int32 ax, ay, bx, by, i;
  363. { int32 axt, ayt, bxt, byt;
  364. unsigned32 b00 = b0;
  365. /*
  366. * If the numbers have 3 digits available and if the leading digits are
  367. * small I do some (minor) normalisation by shifting up by 16 bits. This
  368. * should increase the number of steps that can be taken at once (slightly).
  369. */
  370. if (a0 < (int32)0x8000U && lena > 2)
  371. { a0 = (a0 << 16) | (a1 >> 15);
  372. a1 = ((a1 << 16) | (a[lena-2] >> 15)) & 0x7fffffff;
  373. b00 = (b00 << 16) | (b1 >> 15);
  374. b1 = ((b1 << 16) | (b[lena-2] >> 15)) & 0x7fffffff;
  375. }
  376. next_gcd_step(a0, a1, b00, b1,
  377. &axt, &ayt, &bxt, &byt);
  378. ax = axt; ay = ayt;
  379. bx = bxt; by = byt;
  380. if (ay == 0) goto reduce_by_division;
  381. }
  382. /*
  383. * Now we should be able to arrange
  384. * [ ax ay ] = [ >0 <= 0 ]
  385. * [ bx by ] [ <= 0 > 0 ]
  386. * and I swop the rows to ensure that this is so.
  387. */
  388. if (ax < 0 || by < 0)
  389. { int32 cx = ax, cy = ay;
  390. ax = bx; ay = by;
  391. bx = cx; by = cy;
  392. }
  393. ay = -ay;
  394. bx = -bx; /* Now all variables are positive */
  395. /*
  396. * Now I want to compute ax*a - ay*b
  397. * and by*b - bx*a
  398. * and use these values for the new a and b. Remember that at present
  399. * a and b are just about the same length, and provided that I use b0
  400. * for the leading digit of b I can treat both as having length lena
  401. */
  402. { unsigned32 carryax = 0, carryay = 0,
  403. carrybx = 0, carryby = 0,
  404. borrowa = 1, borrowb = 1,
  405. aix, aiy, bix, biy, aa, bb;
  406. for (i=0; i<lena; i++)
  407. { Dmultiply(carryax, aix, a[i], ax, carryax);
  408. Dmultiply(carryay, aiy, b[i], ay, carryay);
  409. Dmultiply(carrybx, bix, a[i], bx, carrybx);
  410. Dmultiply(carryby, biy, b[i], by, carryby);
  411. aa = aix + clear_top_bit(~aiy) + borrowa;
  412. bb = biy + clear_top_bit(~bix) + borrowb;
  413. borrowa = aa >> 31;
  414. borrowb = bb >> 31;
  415. a[i] = clear_top_bit(aa);
  416. b[i] = clear_top_bit(bb);
  417. }
  418. /*
  419. * I do the top digit by hand to cope with a possible virtual zero digit at
  420. * the head of B.
  421. */
  422. Dmultiply(carryax, aix, a[lena], ax, carryax);
  423. Dmultiply(carryay, aiy, b0, ay, carryay);
  424. Dmultiply(carrybx, bix, a[lena], bx, carrybx);
  425. Dmultiply(carryby, biy, b0, by, carryby);
  426. aa = aix + clear_top_bit(~aiy) + borrowa;
  427. bb = biy + clear_top_bit(~bix) + borrowb;
  428. borrowa = aa >> 31;
  429. borrowb = bb >> 31;
  430. aa = clear_top_bit(aa);
  431. bb = clear_top_bit(bb);
  432. a[lena] = aa;
  433. if (b0 != 0) b[lena] = bb;
  434. lenb = lena;
  435. if (b0 == 0) lenb--;
  436. /*
  437. * The following test is here as a provisional measure - it caught a number of
  438. * bugs etc while I was developing this code. My only worry is that maybe
  439. * the carries and borrows could (correctly) combine to leave zero
  440. * upper digits here without the exact equalities tested here happening.
  441. * I will remove this test after a decent interval.
  442. */
  443. if (carryax - carryay + borrowa != 1 ||
  444. carryby - carrybx + borrowb != 1)
  445. { err_printf("Carries %d \"%s\" %ld %ld %ld %ld %ld %ld\n",
  446. __LINE__, __FILE__,
  447. (long)carryax, (long)carryay, (long)carrybx,
  448. (long)carryby, (long)borrowa, (long)borrowb);
  449. my_exit(EXIT_FAILURE);
  450. }
  451. while (lena > 0 && a[lena] == 0) lena--;
  452. while (lenb > 0 && b[lenb] == 0) lenb--;
  453. }
  454. }
  455. continue;
  456. }
  457. if (flipped) lena |= ~0x7fffffff;
  458. return lena;
  459. }
  460. Lisp_Object gcd(Lisp_Object a, Lisp_Object b)
  461. {
  462. int32 p, q;
  463. if (is_fixnum(a))
  464. { if (!is_fixnum(b))
  465. { if (is_numbers(b) && is_bignum(b))
  466. { if (a == fixnum_of_int(0)) return absb(b);
  467. else b = rembi(b, a);
  468. /*
  469. * a is a fixnum here, so did not need to be stacked over the
  470. * call to rembi()
  471. */
  472. }
  473. else return aerror2("bad arg for gcd", a, b);
  474. }
  475. }
  476. else if (is_numbers(a) && is_bignum(a))
  477. { if (is_fixnum(b))
  478. { if (b == fixnum_of_int(0)) return absb(a);
  479. else a = rembi(a, b);
  480. }
  481. else if (is_numbers(b) && is_bignum(b))
  482. { Lisp_Object nil;
  483. /*
  484. * Now I have a case that maybe I hope is not too common, but which may
  485. * count as the interesting one - the GCD of two bignums. First I ensure
  486. * that the inputs have been made positive and also that I have made copies
  487. * of them - this latter condition is so that it will be proper for me
  488. * to perform remaindering operations on them in-place, thereby reducing the
  489. * total turn-over of memory that I incur.
  490. */
  491. push(b);
  492. if (bignum_minusp(a)) a = negateb(a);
  493. else a = copyb(a);
  494. pop(b);
  495. errexit();
  496. push(a);
  497. if (bignum_minusp(b)) b = negateb(b);
  498. else b = copyb(b);
  499. pop(a);
  500. errexit();
  501. /*
  502. * Note that negating a NEGATIVE bignum may sometimes make it grow by one
  503. * word, but can never cause it to shrink - and in particular never shrink to
  504. * a smallnum. Of course negating a positive bignum can (in just one case!)
  505. * give a fixnum - but that can not occur here.
  506. */
  507. {
  508. int32 lena, lenb, new_lena;
  509. unsigned32 b0;
  510. /*
  511. * I apply two ideas here. The first is to perform all my arithmetic
  512. * in-place, since I have ensured that the numbers I am working with are
  513. * fresh copies. The second is to defer true bignum operations for as
  514. * long as I can by starting a remainder sequence using just the leading
  515. * digits of the inputs.
  516. */
  517. lena = (bignum_length(a) >> 2) - 2;
  518. lenb = (bignum_length(b) >> 2) - 2;
  519. new_lena = huge_gcd(&bignum_digits(a)[0], lena,
  520. &bignum_digits(b)[0], lenb);
  521. /*
  522. * The result handed back (new_lena here) contains not only the revised
  523. * length of a, but also a flag bit (handed back in its sign bit) to
  524. * indicate whether A and B have been swopped.
  525. */
  526. if (new_lena < 0)
  527. { Lisp_Object c = a;
  528. a = b;
  529. b = c;
  530. new_lena = clear_top_bit(new_lena);
  531. }
  532. /*
  533. * By this stage I have reduced A and B so that B is a single-precision
  534. * bignum (i.e. its value is at most 0x7fffffff). A special case will be
  535. * when B==0. To complete the GCD process I need to do a single remainder
  536. * operation (A%B) after which I have just machine arithmetic to do to
  537. * complete the job.
  538. */
  539. b0 = bignum_digits(b)[0];
  540. if (b0 == 0)
  541. { int32 a0 = bignum_digits(a)[new_lena];
  542. /*
  543. * The leading digit of a bignum is in effect one bit shorter than the
  544. * others (to allow for the fact that it is signed). In huge_gcd I did
  545. * not worry about that, but here (before I return) I need to restore a
  546. * proper state. Note that since the GCD is no larger than either original
  547. * number I am guaranteed to have space to put the padding zero I may need
  548. * to stick onto the number...
  549. */
  550. if ((a0 & 0x40000000) != 0)
  551. bignum_digits(a)[++new_lena] = 0;
  552. lena = (bignum_length(a) >> 2) - 2;
  553. numhdr(a) = make_bighdr(new_lena+2);
  554. lena = (lena + 1) & 0xfffffffeU;
  555. new_lena = (new_lena + 1) & 0xfffffffeU;
  556. if (new_lena != lena)
  557. bignum_digits(a)[new_lena+1] =
  558. make_bighdr(lena - new_lena);
  559. return a;
  560. }
  561. /*
  562. * Another special case is if we have just discovered that the numbers were
  563. * co-prime.
  564. */
  565. else if (b0 == 1) return fixnum_of_int(1);
  566. p = bignum_digits(b)[0];
  567. if (new_lena == 0) q = bignum_digits(a)[0];
  568. else
  569. { q = bignum_digits(a)[new_lena] % p;
  570. while (new_lena > 0)
  571. { unsigned32 qtemp;
  572. Ddivide(q, qtemp, q,
  573. bignum_digits(a)[--new_lena], p);
  574. }
  575. }
  576. if (p < q)
  577. { int32 r = p;
  578. p = q;
  579. q = r;
  580. }
  581. goto gcd_using_machine_arithmetic;
  582. }
  583. /*
  584. * The next 4 lines seem to be orphan code, no longer reachable.
  585. if (b == fixnum_of_int(0)) return a;
  586. a = rembi(a, b);
  587. errexit();
  588. */
  589. }
  590. else return aerror2("bad arg for gcd", a, b);
  591. }
  592. else return aerror2("bad arg for gcd", a, b);
  593. /*
  594. * If I drop out of the above IF statement I have reduced a and b to
  595. * fixnums, which I can compute with directly using C native arithmetic.
  596. */
  597. p = int_of_fixnum(a);
  598. q = int_of_fixnum(b);
  599. if (p < 0) p = -p;
  600. if (q < 0) q = -q;
  601. gcd_using_machine_arithmetic:
  602. #ifndef FAST_DIVISION
  603. /*
  604. * If your computer has a slow implementation of the C remainder
  605. * operation (p % q) but fast shifts then it may be worthwhile
  606. * implementing integer GCD thusly... On an ARM where division is
  607. * done in software my time tests showed the shift-and-subtract GCD
  608. * code over twice as fast as the version using the remainder operator.
  609. * Somewhat to my amazement, most other targets (at least when I use -O
  610. * to optimise this code) show this version faster than the more
  611. * obvious code. See also the discussion in Knuth vol II.
  612. */
  613. if (p == 0) p = q;
  614. else if (q != 0)
  615. { int twos = 0;
  616. /*
  617. * I shift p and q right until both are odd numbers, counting the
  618. * power of two that was needed for the GCD.
  619. * The contorted code here tries to avoid redundant tests on the
  620. * bottom bits of p and q.
  621. */
  622. for (;;)
  623. { if ((p & 1) == 0)
  624. { if ((q & 1) == 0)
  625. { p = p >> 1;
  626. q = q >> 1;
  627. twos++;
  628. continue;
  629. }
  630. do p = p >> 1; while ((p & 1) == 0);
  631. break;
  632. }
  633. while ((q & 1) == 0) q = q >> 1;
  634. break;
  635. }
  636. /*
  637. * Now p and q are both odd, so if I subtract one from the other
  638. * I get an even number that can properly be shifted right (because
  639. * multiples of 2 have already all be taken care of). On some RISC
  640. * architectures this test-and-subtract loop will run only a bit slower
  641. * than just one division operation, especially if the two numbers p and
  642. * q are small.
  643. */
  644. while (p != q)
  645. { if (p > q)
  646. { p = p - q;
  647. do p = p >> 1; while ((p & 1) == 0);
  648. }
  649. else
  650. { q = q - p;
  651. do q = q >> 1; while ((q & 1) == 0);
  652. }
  653. }
  654. /*
  655. * Finally I must re-instate the power of two that was taken out
  656. * earlier.
  657. */
  658. p = p << twos;
  659. }
  660. #else /* FAST_DIVISION */
  661. if (p < q)
  662. { int32 t = p;
  663. p = q;
  664. q = t;
  665. }
  666. while (q != 0)
  667. { int32 t = p % q;
  668. p = q;
  669. q = t;
  670. }
  671. #endif /* FAST_DIVISION */
  672. /*
  673. * In some cases the result will be a bignum. Even with fixnum inputs
  674. * gcd(-0x08000000, -0x08000000) == 0x08000000 which is a bignum. Yuk!
  675. * What is worse, in the case that I get here out of the gcd(big,big) code
  676. * I can end up with a value that needs to be a 2-word bignum - that happens
  677. * when the result is of the form #b01xx...
  678. */
  679. if ((p & 0x40000000) != 0) return make_two_word_bignum(0, p);
  680. else if (p >= 0x08000000) return make_one_word_bignum(p);
  681. else return fixnum_of_int(p);
  682. }
  683. Lisp_Object lcm(Lisp_Object a, Lisp_Object b)
  684. {
  685. Lisp_Object g, nil = C_nil;
  686. if (a == fixnum_of_int(0) ||
  687. b == fixnum_of_int(0)) return fixnum_of_int(0);
  688. stackcheck2(0, a, b);
  689. push2(a, b);
  690. g = gcd(a, b);
  691. errexitn(2);
  692. pop(b);
  693. b = quot2(b, g);
  694. errexitn(1);
  695. /*
  696. * b has already been through quot2(), so minusp can not fail...
  697. */
  698. if (minusp(b)) b = negate(b);
  699. pop(a);
  700. errexit();
  701. if (minusp(a)) /* can not fail */
  702. { push(b);
  703. a = negate(a);
  704. pop(b);
  705. }
  706. errexit();
  707. return times2(a, b);
  708. }
  709. Lisp_Object lognot(Lisp_Object a)
  710. {
  711. /*
  712. * bitwise negation can never cause a fixnum to need to grow into
  713. * a bignum. For bignums I implement ~a as -(a+1).
  714. */
  715. if (is_fixnum(a)) return (Lisp_Object)((int32)a ^ ((-1) << 4));
  716. else if (is_numbers(a) && is_bignum(a))
  717. { Lisp_Object nil;
  718. a = plus2(a, fixnum_of_int(1));
  719. errexit();
  720. return negate(a);
  721. }
  722. else return aerror1("Bad arg for xxx", a);
  723. }
  724. #ifdef __powerc
  725. /* If you have trouble compiling this just comment it out, please */
  726. #pragma options(!global_optimizer)
  727. #endif
  728. Lisp_Object ash(Lisp_Object a, Lisp_Object b)
  729. /*
  730. * Shift A left if B is positive, or right if B is negative. Right shifts
  731. * are arithmetic, i.e. as if 2s-complement values are used with negative
  732. * values having an infinite number of leading '1' bits.
  733. */
  734. {
  735. int32 bb;
  736. if (!is_fixnum(b)) return aerror2("bad arg for lshift", a, b);
  737. bb = int_of_fixnum(b);
  738. if (bb == 0) return a; /* Shifting by zero has no effect */
  739. if (is_fixnum(a))
  740. { int32 aa = int_of_fixnum(a);
  741. if (aa == 0) return a; /* Shifting zero leaves it unaltered */
  742. if (bb < 0)
  743. { bb = -bb;
  744. /*
  745. * Fixnums have only 28 data bits in them, and so right shifts by more than
  746. * that will lead to a result that is all 1s or all 0s. If I assume that
  747. * I am working with 32 bit words I can let a shift by 30 bits achieve this
  748. * effect.
  749. */
  750. if (bb > 30) bb = 30;
  751. #ifdef SIGNED_SHIFTS_ARE_LOGICAL
  752. /*
  753. * ANSI C (oh bother it) permits an implementation to have right shifts
  754. * on signed values as logical (ie. shifting in zeros into the vacated
  755. * positions. In that case since I really want an arithmetic shift here
  756. * I need to insert '1' bits by hand.
  757. */
  758. if (aa < 0)
  759. { aa = aa >> bb;
  760. aa |= (((int32)-1) << (32 - bb));
  761. }
  762. else
  763. #endif
  764. aa = aa >> bb;
  765. return fixnum_of_int(aa);
  766. }
  767. else if (bb < 31)
  768. { int32 ah = aa >> (31 - bb);
  769. #ifdef SIGNED_SHIFTS_ARE_LOGICAL
  770. if (aa < 0) ah |= (((int32)-1) << (bb+1));
  771. #endif
  772. aa = aa << bb;
  773. /*
  774. * Here (ah,aa) is a double-precision representation of the left-shifted
  775. * value. Note that this has just 31 valid bits in aa (but I have not
  776. * yet masked the top bit down to zero). Because a fixnum has only 28 bits
  777. * this can be at worst a 2-word bignum. But it may be a 1-word bignum or
  778. * a fixnum, and I can spend much effort deciding which!
  779. */
  780. if (ah == 0 && aa >= 0 && aa < 0x40000000)
  781. { if (aa < 0x08000000) return fixnum_of_int(aa);
  782. else return make_one_word_bignum(aa);
  783. }
  784. else if (ah == -1 && aa < 0 && aa >= -0x40000000)
  785. { if (aa >= -0x08000000) return fixnum_of_int(aa);
  786. else return make_one_word_bignum(aa);
  787. }
  788. return make_two_word_bignum(ah, clear_top_bit(aa));
  789. }
  790. else
  791. {
  792. Lisp_Object nil;
  793. /*
  794. * I drop through to here for a left-shift that will need to give a
  795. * bignum result, since the shift will be by at least 31 and the value
  796. * being shifted was non-zero. I deal with this by making the input into
  797. * bignum representation (though it would not generally be valid as one),
  798. * and dropping through to the general bignum shift code.
  799. */
  800. a = make_one_word_bignum(aa);
  801. errexit();
  802. /*
  803. * DROP THROUGH from here and pick up the general bignum shift code
  804. */
  805. }
  806. }
  807. else if (!is_numbers(a) || !is_bignum(a))
  808. return aerror2("bad arg for lshift", a, b);
  809. /*
  810. * Bignum case here
  811. */
  812. if (bb > 0)
  813. { int32 lena = (bignum_length(a) >> 2)-2;
  814. int32 words = bb / 31; /* words to shift left by */
  815. int32 bits = bb % 31; /* bits to shift left by */
  816. int32 msd = bignum_digits(a)[lena];
  817. int32 d0 = msd >> (31 - bits);
  818. int32 d1 = clear_top_bit(msd << bits);
  819. int32 i, lenc = lena + words;
  820. CSLbool longer = NO;
  821. Lisp_Object c, nil;
  822. #ifdef SIGNED_SHIFTS_ARE_LOGICAL
  823. if (msd < 0) d0 |= (((int32)-1) << (bits+1));
  824. #endif
  825. if (!((d0 == 0 && (d1 & 0x40000000) == 0) ||
  826. (d0 == -1 && (d1 & 0x40000000) != 0)))
  827. lenc++, longer = YES;
  828. push(a);
  829. c = getvector(TAG_NUMBERS, TYPE_BIGNUM, (lenc+2)<<2);
  830. pop(a);
  831. errexit();
  832. /*
  833. * Before I do anything else I will fill the result-vector with zero, so that
  834. * the parts that do not get A copied in will end up in a proper state. This
  835. * should include the word that pads the vector out to an even number of
  836. * words.
  837. */
  838. for (i=0; i<=lenc; i++) bignum_digits(c)[i] = 0;
  839. if ((lenc & 1) != 0) bignum_digits(c)[i] = 0; /* The spare word */
  840. d0 = 0;
  841. for (i=0; i<=lena; i++)
  842. { d1 = bignum_digits(a)[i];
  843. /*
  844. * The value of d0 here is positive, so there are no nasty issues of
  845. * logical vs arithmetic shifts to bother me.
  846. */
  847. bignum_digits(c)[words + i] =
  848. (d0 >> (31 - bits)) | clear_top_bit(d1 << bits);
  849. d0 = d1;
  850. }
  851. if (longer)
  852. { bignum_digits(c)[words+i] = d0 >> (31 - bits);
  853. #ifdef SIGNED_SHIFTS_ARE_LOGICAL
  854. if (d0 < 0) bignum_digits(c)[words+i] |= (((int32)-1) << (bits+1));
  855. #endif
  856. }
  857. else if (msd < 0) bignum_digits(c)[words+i-1] |= ~0x7fffffff;
  858. return c;
  859. }
  860. else
  861. /*
  862. * Here for bignum right-shifts.
  863. */
  864. { int32 lena = (bignum_length(a) >> 2)-2;
  865. int32 words = (-bb) / 31; /* words to shift right by */
  866. int32 bits = (-bb) % 31; /* bits to shift right by */
  867. int32 msd = bignum_digits(a)[lena];
  868. int32 d0 = msd >> bits;
  869. int32 d1 = clear_top_bit(msd << (31 - bits));
  870. int32 i, lenc = lena - words;
  871. CSLbool shorter = NO;
  872. Lisp_Object c, nil;
  873. #ifdef SIGNED_SHIFTS_ARE_LOGICAL
  874. if (msd < 0) d0 |= (((int32)-1) << (31 - bits));
  875. #endif
  876. if (bits != 0 &&
  877. ((d0 == 0 && (d1 & 0x40000000) == 0) ||
  878. (d0 == -1 && (d1 & 0x40000000) != 0)))
  879. lenc--, shorter = YES;
  880. /*
  881. * Maybe at this stage I can tell that the result will be zero (or -1).
  882. * If the result will be a single-precision value I will nevertheless
  883. * build it in a one-word bignum and then (if appropriate) extract the
  884. * fixnum value. This is slightly wasteful, but I do not (at present)
  885. * view right-shifting a bignum to get a fixnum as super speed-critical.
  886. */
  887. if (lenc < 0) return fixnum_of_int(msd < 0 ? -1 : 0);
  888. push(a);
  889. c = getvector(TAG_NUMBERS, TYPE_BIGNUM, (lenc+2)<<2);
  890. pop(a);
  891. errexit();
  892. if ((lenc & 1) != 0) bignum_digits(c)[lenc+1] = 0;/* The spare word */
  893. d0 = bignum_digits(a)[words];
  894. for (i=0; i<lenc; i++)
  895. { d1 = bignum_digits(a)[words+i+1];
  896. bignum_digits(c)[i] =
  897. (d0 >> bits) | clear_top_bit(d1 << (31 - bits));
  898. d0 = d1;
  899. }
  900. d1 = shorter ? msd : (msd < 0 ? -1 : 0);
  901. bignum_digits(c)[i] =
  902. (d0 >> bits) | (d1 << (31 - bits));
  903. /*
  904. * Now I see if the result ought to be represented as a fixnum.
  905. */
  906. if (lenc == 0)
  907. { d0 = bignum_digits(c)[0];
  908. d1 = d0 & (-0x08000000);
  909. if (d1 == 0 || d1 == -0x08000000) return fixnum_of_int(d0);
  910. }
  911. /*
  912. * Drop through if a genuine bignum result is needed.
  913. */
  914. return c;
  915. }
  916. }
  917. #ifdef __powerc
  918. /* If you have trouble compiling this just comment it out, please */
  919. #pragma options(global_optimizer)
  920. #endif
  921. Lisp_Object shrink_bignum(Lisp_Object a, int32 lena)
  922. { int32 msd = bignum_digits(a)[lena];
  923. int32 olen = lena;
  924. if (msd == 0)
  925. { while (lena > 0)
  926. { lena--;
  927. msd = bignum_digits(a)[lena];
  928. if (msd != 0) break;
  929. }
  930. if ((msd & 0x40000000) != 0) lena++;
  931. }
  932. else if (msd == -1)
  933. { while (lena > 0)
  934. { lena--;
  935. msd = bignum_digits(a)[lena];
  936. if (msd != 0x7fffffff) break;
  937. }
  938. if ((msd & 0x40000000) == 0) lena++;
  939. }
  940. if (lena == 0)
  941. { int32 w = msd & 0x78000000;
  942. if (w == 0 || w == 0x78000000) return fixnum_of_int(msd);
  943. }
  944. if (lena == olen) return a;
  945. /*
  946. * Here I had allocated too much space, so I have to trim it off and
  947. * put a dummy vector in to pad out the heap.
  948. */
  949. numhdr(a) -= pack_hdrlength(olen-lena);
  950. msd = bignum_digits(a)[lena];
  951. if ((msd & 0x40000000) != 0) bignum_digits(a)[lena] = msd | ~0x7fffffff;
  952. if ((lena & 1) != 0) bignum_digits(a)[++lena] = 0;
  953. lena++;
  954. olen = (olen+1)|1;
  955. if (lena == olen) return a;
  956. bignum_digits(a)[lena]=make_bighdr(olen-lena);
  957. return a;
  958. }
  959. static Lisp_Object logiorbb(Lisp_Object a, Lisp_Object b)
  960. { Lisp_Object nil;
  961. int32 lena, lenb, i, msd;
  962. errexit(); /* failure in make_one_word_bignum()? */
  963. lena = (bignum_length(a) >> 2) - 2;
  964. lenb = (bignum_length(b) >> 2) - 2;
  965. if (lena > lenb)
  966. { Lisp_Object c = a;
  967. int32 lenc = lena;
  968. a = b; lena = lenb;
  969. b = c; lenb = lenc;
  970. }
  971. /* Now b is at least as long as a */
  972. msd = bignum_digits(a)[lena];
  973. if (msd < 0)
  974. { push(b);
  975. a = copyb(a);
  976. pop(b);
  977. errexit();
  978. for (i=0; i<=lena; i++) bignum_digits(a)[i] |= bignum_digits(b)[i];
  979. }
  980. else
  981. { push(a);
  982. b = copyb(b);
  983. pop(a);
  984. errexit();
  985. for (i=0; i<=lena; i++) bignum_digits(b)[i] |= bignum_digits(a)[i];
  986. if (lena != lenb) return b;
  987. a = b;
  988. }
  989. return shrink_bignum(a, lena);
  990. }
  991. static Lisp_Object logiorib(Lisp_Object a, Lisp_Object b)
  992. {
  993. push(b);
  994. a = make_one_word_bignum(int_of_fixnum(a));
  995. pop(b);
  996. return logiorbb(a, b);
  997. }
  998. Lisp_Object logior2(Lisp_Object a, Lisp_Object b)
  999. {
  1000. if (is_fixnum(a))
  1001. { if (is_fixnum(b)) return (Lisp_Object)((int32)a | (int32)b);
  1002. else if (is_numbers(b) && is_bignum(b)) return logiorib(a, b);
  1003. else return aerror2("bad arg for logior", a, b);
  1004. }
  1005. else if (is_numbers(a) && is_bignum(a))
  1006. { if (is_fixnum(b)) return logiorib(b, a);
  1007. else if (is_numbers(b) && is_bignum(b)) return logiorbb(a, b);
  1008. else return aerror2("bad arg for logior", a, b);
  1009. }
  1010. else return aerror2("bad arg for logior", a, b);
  1011. }
  1012. static Lisp_Object logxorbb(Lisp_Object a, Lisp_Object b)
  1013. { Lisp_Object nil;
  1014. int32 lena, lenb, i;
  1015. unsigned32 w;
  1016. errexit(); /* failure in make_one_word_bignum()? */
  1017. lena = (bignum_length(a) >> 2) - 2;
  1018. lenb = (bignum_length(b) >> 2) - 2;
  1019. if (lena > lenb)
  1020. { Lisp_Object c = a;
  1021. int32 lenc = lena;
  1022. a = b; lena = lenb;
  1023. b = c; lenb = lenc;
  1024. }
  1025. /* Now b is at least as long as a */
  1026. push(a);
  1027. b = copyb(b);
  1028. pop(a);
  1029. errexit();
  1030. for (i=0; i<lena; i++) bignum_digits(b)[i] ^= bignum_digits(a)[i];
  1031. w = bignum_digits(a)[i];
  1032. if (lena == lenb) bignum_digits(b)[i] ^= w;
  1033. else
  1034. { bignum_digits(b)[i] ^= clear_top_bit(w);
  1035. if ((w & 0x80000000U) != 0)
  1036. { for(i++; i<lenb; i++)
  1037. bignum_digits(b)[i] = clear_top_bit(~bignum_digits(b)[i]);
  1038. bignum_digits(b)[i] = ~bignum_digits(b)[i];
  1039. }
  1040. }
  1041. return shrink_bignum(b, lenb);
  1042. }
  1043. static Lisp_Object logxorib(Lisp_Object a, Lisp_Object b)
  1044. {
  1045. push(b);
  1046. a = make_one_word_bignum(int_of_fixnum(a));
  1047. pop(b);
  1048. return logxorbb(a, b);
  1049. }
  1050. Lisp_Object logxor2(Lisp_Object a, Lisp_Object b)
  1051. {
  1052. if (is_fixnum(a))
  1053. { if (is_fixnum(b))
  1054. return (Lisp_Object)(((int32)a ^ (int32)b) + TAG_FIXNUM);
  1055. else if (is_numbers(b) && is_bignum(b)) return logxorib(a, b);
  1056. else return aerror2("bad arg for logxor", a, b);
  1057. }
  1058. else if (is_numbers(a) && is_bignum(a))
  1059. { if (is_fixnum(b)) return logxorib(b, a);
  1060. else if (is_numbers(b) && is_bignum(b)) return logxorbb(a, b);
  1061. else return aerror2("bad arg for logxor", a, b);
  1062. }
  1063. else return aerror2("bad arg for logxor", a, b);
  1064. }
  1065. Lisp_Object logeqv2(Lisp_Object a, Lisp_Object b)
  1066. {
  1067. if (is_fixnum(a))
  1068. { if (is_fixnum(b))
  1069. return (Lisp_Object)((int32)a ^ (int32)b ^
  1070. (int32)fixnum_of_int(-1));
  1071. else if (is_numbers(b) && is_bignum(b))
  1072. { push(b);
  1073. a = make_one_word_bignum(~int_of_fixnum(a));
  1074. pop(b);
  1075. return logxorbb(a, b);
  1076. }
  1077. else return aerror2("bad arg for logeqv", a, b);
  1078. }
  1079. else if (is_numbers(a) && is_bignum(a))
  1080. { if (is_fixnum(b))
  1081. { push(a);
  1082. b = make_one_word_bignum(~int_of_fixnum(b));
  1083. pop(a);
  1084. return logxorbb(b, a);
  1085. }
  1086. else if (is_numbers(b) && is_bignum(b))
  1087. { Lisp_Object nil;
  1088. push(a);
  1089. b = lognot(b);
  1090. pop(a);
  1091. errexit();
  1092. return logxorbb(a, b);
  1093. }
  1094. else return aerror2("bad arg for logeqv", a, b);
  1095. }
  1096. else return aerror2("bad arg for logeqv", a, b);
  1097. }
  1098. static Lisp_Object logandbb(Lisp_Object a, Lisp_Object b)
  1099. { Lisp_Object nil;
  1100. int32 lena, lenb, i, msd;
  1101. errexit(); /* failure in make_one_word_bignum()? */
  1102. lena = (bignum_length(a) >> 2) - 2;
  1103. lenb = (bignum_length(b) >> 2) - 2;
  1104. if (lena > lenb)
  1105. { Lisp_Object c = a;
  1106. int32 lenc = lena;
  1107. a = b; lena = lenb;
  1108. b = c; lenb = lenc;
  1109. }
  1110. /* Now b is at least as long as a */
  1111. msd = bignum_digits(a)[lena];
  1112. if (msd >= 0)
  1113. { push(b);
  1114. a = copyb(a);
  1115. pop(b);
  1116. errexit();
  1117. for (i=0; i<=lena; i++) bignum_digits(a)[i] &= bignum_digits(b)[i];
  1118. }
  1119. else
  1120. { push(a);
  1121. b = copyb(b);
  1122. pop(a);
  1123. errexit();
  1124. for (i=0; i<=lena; i++) bignum_digits(b)[i] &= bignum_digits(a)[i];
  1125. if (lena != lenb) return b;
  1126. a = b;
  1127. }
  1128. return shrink_bignum(a, lena);
  1129. }
  1130. static Lisp_Object logandib(Lisp_Object a, Lisp_Object b)
  1131. {
  1132. push(b);
  1133. a = make_one_word_bignum(int_of_fixnum(a));
  1134. pop(b);
  1135. return logandbb(a, b);
  1136. }
  1137. Lisp_Object logand2(Lisp_Object a, Lisp_Object b)
  1138. {
  1139. if (is_fixnum(a))
  1140. { if (is_fixnum(b)) return (Lisp_Object)((int32)a & (int32)b);
  1141. else if (is_numbers(b) && is_bignum(b)) return logandib(a, b);
  1142. else return aerror2("bad arg for logand", a, b);
  1143. }
  1144. else if (is_numbers(a) && is_bignum(a))
  1145. { if (is_fixnum(b)) return logandib(b, a);
  1146. else if (is_numbers(b) && is_bignum(b)) return logandbb(a, b);
  1147. else return aerror2("bad arg for logand", a, b);
  1148. }
  1149. else return aerror2("bad arg for logand", a, b);
  1150. }
  1151. /* end of arith09.c */