arith09.c 44 KB

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