arith01.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. /* arith01.c Copyright (C) 1990 Codemist Ltd */
  2. /*
  3. * Arithmetic functions.
  4. * Addition of generic numbers
  5. * and in particular a lot of bignum support.
  6. *
  7. * Version 1.4 November 1990.
  8. *
  9. */
  10. /* Signature: 07d5049f 23-Jan-1999 */
  11. #include <stdarg.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14. #include <math.h>
  15. #include "machine.h"
  16. #include "tags.h"
  17. #include "cslerror.h"
  18. #include "externs.h"
  19. #include "arith.h"
  20. #ifdef TIMEOUT
  21. #include "timeout.h"
  22. #endif
  23. /*
  24. * I start off with a collection of utility functions that create
  25. * Lisp structures to represent various sorts of numbers
  26. * and which extract values from same.
  27. * The typedefs that explain the layout of these structures are in "tags.h"
  28. */
  29. Lisp_Object make_one_word_bignum(int32 n)
  30. /*
  31. * n is an integer - create a bignum representation of it. This is
  32. * done when n is outside the range 0xf8000000 to 0x07ffffff.
  33. */
  34. { Lisp_Object w = getvector(TAG_NUMBERS, TYPE_BIGNUM, 8);
  35. Lisp_Object nil;
  36. errexit();
  37. bignum_digits(w)[0] = n;
  38. return w;
  39. }
  40. Lisp_Object make_two_word_bignum(int32 a1, unsigned32 a0)
  41. /*
  42. * This make a 2-word bignum from the 2-word value (a1,a0), where it
  43. * must have been arranged already that a1 and a0 are correctly
  44. * normalized to put in the two words as indicated.
  45. */
  46. {
  47. Lisp_Object w = getvector(TAG_NUMBERS, TYPE_BIGNUM, 12);
  48. Lisp_Object nil;
  49. errexit();
  50. bignum_digits(w)[0] = a0;
  51. bignum_digits(w)[1] = a1;
  52. bignum_digits(w)[2] = 0;
  53. return w;
  54. }
  55. #ifdef COMMON
  56. Lisp_Object make_sfloat(double d)
  57. /*
  58. * Turn a regular floating point value into a Lisp "short float", which
  59. * is an immediate object obtained by using the bottom 4 bits of a 32-bit
  60. * word as tag, and the rest as just whatever would stand for a regular
  61. * single precision value. In doing the conversion here I ignore
  62. * rounding etc - short floats are to save heap turn-over, but will
  63. * not give robust numeric results.
  64. */
  65. {
  66. Float_union w;
  67. w.f = (float)d;
  68. return (w.i & ~(int32)0xf) + TAG_SFLOAT;
  69. }
  70. #endif
  71. Lisp_Object make_boxfloat(double a, int32 type)
  72. /*
  73. * Make a boxed float (single, double or long according to the type specifier)
  74. * if type==0 this makes a short float
  75. */
  76. {
  77. Lisp_Object r, nil;
  78. #ifndef COMMON
  79. CSL_IGNORE(type);
  80. #endif
  81. #ifdef COMMON
  82. switch (type)
  83. {
  84. case 0:
  85. { Float_union aa;
  86. aa.f = (float)a;
  87. return (aa.i & ~(int32)0xf) + TAG_SFLOAT;
  88. }
  89. case TYPE_SINGLE_FLOAT:
  90. r = getvector(TAG_BOXFLOAT, TYPE_SINGLE_FLOAT, sizeof(Single_Float));
  91. errexit();
  92. single_float_val(r) = (float)a;
  93. return r;
  94. default: /* TYPE_DOUBLE_FLOAT I hope */
  95. #endif
  96. r = getvector(TAG_BOXFLOAT, TYPE_DOUBLE_FLOAT, sizeof(Double_Float));
  97. errexit();
  98. double_float_val(r) = a;
  99. return r;
  100. #ifdef COMMON
  101. case TYPE_LONG_FLOAT:
  102. r = getvector(TAG_BOXFLOAT, TYPE_LONG_FLOAT, sizeof(Long_Float));
  103. errexit();
  104. long_float_val(r) = a;
  105. return r;
  106. }
  107. #endif
  108. }
  109. static double bignum_to_float(Lisp_Object v, int32 h, int *xp)
  110. /*
  111. * Convert a Lisp bignum to get a floating point value. This uses at most the
  112. * top 3 digits of the bignum's representation since that is enough to achieve
  113. * full double precision accuracy.
  114. * This can not overflow, because it leaves an exponent-adjustment value
  115. * in *xp. You need ldexp(r, *xp) afterwards.
  116. */
  117. {
  118. int32 n = (h>>2) - 2; /* Last index into the data */
  119. int x = 31*(int)n;
  120. int32 msd = (int32)bignum_digits(v)[n];
  121. /* NB signed conversion on next line */
  122. double r = (double)msd;
  123. switch (n)
  124. {
  125. default: /* for very big numbers combine in 3 digits */
  126. r = TWO_31*r + (double)bignum_digits(v)[--n];
  127. x -= 31;
  128. /* drop through */
  129. case 1: r = TWO_31*r + (double)bignum_digits(v)[--n];
  130. x -= 31;
  131. /* drop through */
  132. case 0: break; /* do no more */
  133. }
  134. *xp = x;
  135. return r;
  136. }
  137. double float_of_number(Lisp_Object a)
  138. /*
  139. * Return a (double precision) floating point value for the given Lisp
  140. * number, or 0.0 in case of trouble. This is often called in circumstances
  141. * where I already know the type of its argument and so its type-dispatch
  142. * is unnecessary - in doing so I am trading off performance against
  143. * code repetition.
  144. */
  145. {
  146. if (is_fixnum(a)) return (double)int_of_fixnum(a);
  147. #ifdef COMMON
  148. else if (is_sfloat(a))
  149. { Float_union w;
  150. w.i = a - TAG_SFLOAT;
  151. return (double)w.f;
  152. }
  153. #endif
  154. else if (is_bfloat(a))
  155. { int32 h = type_of_header(flthdr(a));
  156. switch (h)
  157. {
  158. #ifdef COMMON
  159. case TYPE_SINGLE_FLOAT:
  160. return (double)single_float_val(a);
  161. #endif
  162. case TYPE_DOUBLE_FLOAT:
  163. return double_float_val(a);
  164. #ifdef COMMON
  165. case TYPE_LONG_FLOAT:
  166. return (double)long_float_val(a);
  167. #endif
  168. default:
  169. return 0.0;
  170. }
  171. }
  172. else
  173. { Header h = numhdr(a);
  174. int x1;
  175. double r1;
  176. switch (type_of_header(h))
  177. {
  178. case TYPE_BIGNUM:
  179. r1 = bignum_to_float(a, length_of_header(h), &x1);
  180. return ldexp(r1, x1);
  181. #ifdef COMMON
  182. case TYPE_RATNUM:
  183. { int x2;
  184. Lisp_Object na = numerator(a);
  185. a = denominator(a);
  186. if (is_fixnum(na)) r1 = float_of_number(na), x1 = 0;
  187. else r1 = bignum_to_float(na,
  188. length_of_header(numhdr(na)), &x1);
  189. if (is_fixnum(a)) r1 = r1 / float_of_number(a), x2 = 0;
  190. else r1 = r1 / bignum_to_float(a,
  191. length_of_header(numhdr(a)), &x2);
  192. /* Floating point overflow can only arise in this ldexp() */
  193. return ldexp(r1, x1 - x2);
  194. }
  195. #endif
  196. default:
  197. /*
  198. * If the value was non-numeric or a complex number I hand back 0.0,
  199. * and since I am supposed to have checked the object type already
  200. * this OUGHT not to arrive - bit raising an exception seems over-keen.
  201. */
  202. return 0.0;
  203. }
  204. }
  205. }
  206. int32 thirty_two_bits(Lisp_Object a)
  207. /*
  208. * return a 32 bit integer value for the Lisp integer (fixnum or bignum)
  209. * passed down - ignore any higher order bits and return 0 if the arg was
  210. * floating, rational etc or not a number at all. Only really wanted where
  211. * links between C-specific code (that might really want 32-bit values)
  212. * and Lisp are being coded.
  213. */
  214. {
  215. switch ((int)a & TAG_BITS)
  216. {
  217. case TAG_FIXNUM:
  218. return int_of_fixnum(a);
  219. case TAG_NUMBERS:
  220. if (is_bignum(a))
  221. { int len = bignum_length(a);
  222. /*
  223. * Note that I keep 31 bits per word and use a 2s complement representation.
  224. * thus if I have a one-word bignum I just want its contents but in all
  225. * other cases I need just one bit from the next word up.
  226. */
  227. if (len == 8) return bignum_digits(a)[0]; /* One word bignum */
  228. return bignum_digits(a)[0] | (bignum_digits(a)[1] << 31);
  229. }
  230. /* else drop through */
  231. case TAG_BOXFLOAT:
  232. default:
  233. /*
  234. * return 0 for all non-fixnums
  235. */
  236. return 0;
  237. }
  238. }
  239. #ifdef COMMON
  240. Lisp_Object make_complex(Lisp_Object r, Lisp_Object i)
  241. {
  242. Lisp_Object v, nil = C_nil;
  243. /*
  244. * Here r and i are expected to be either both rational (which in this
  245. * context includes the case of integer values) or both of the same
  246. * floating point type. It is assumed that this has already been
  247. * arranged by here.
  248. */
  249. if (i == fixnum_of_int(0)) return r;
  250. stackcheck2(0, r, i);
  251. push2(r, i);
  252. v = getvector(TAG_NUMBERS, TYPE_COMPLEX_NUM, sizeof(Complex_Number));
  253. /*
  254. * The vector r has uninitialized contents here - dodgy. If the call
  255. * to getvector succeeded then I fill it in, otherwise I will not
  256. * refer to it again, and I think that unreferenced vectors containing junk
  257. * are OK.
  258. */
  259. pop2(i, r);
  260. errexit();
  261. real_part(v) = r;
  262. imag_part(v) = i;
  263. return v;
  264. }
  265. Lisp_Object make_ratio(Lisp_Object p, Lisp_Object q)
  266. /*
  267. * By the time this is called (p/q) must be in its lowest terms, q>0
  268. */
  269. {
  270. Lisp_Object v, nil = C_nil;
  271. if (q == fixnum_of_int(1)) return p;
  272. stackcheck2(0, p, q);
  273. push2(p, q);
  274. v = getvector(TAG_NUMBERS, TYPE_RATNUM, sizeof(Rational_Number));
  275. pop2(q, p);
  276. errexit();
  277. numerator(v) = p;
  278. denominator(v) = q;
  279. return v;
  280. }
  281. #endif
  282. /*
  283. * The next bit of code seems pretty dreadful, but I think that is just
  284. * what generic arithmetic is all about. The code for plus2 is written
  285. * as a dispatch function into over 30 separate possible type-specific
  286. * versions of the code. In a very few simple (and performance-critical)
  287. * cases the code is written in-line in plus2 - in particular arithmetic
  288. * on fixnums is done that way. Similarly for other cases.
  289. * I Use one-character suffices to remind me about types:
  290. * i fixnum
  291. * b bignum
  292. * r ratio
  293. * s short float
  294. * f boxed float (single/double/long)
  295. * c complex
  296. *
  297. * Throughout this code I am going to IGNORE floating point exceptions,
  298. * at least for a first attempt. Decent detection of and recovery after
  299. * floating point overflow seems an extra unpleasant distraction! Note
  300. * that C allows me to trap the SIGFPE exception, but returning from
  301. * the exception handler gives undefined behaviour - one is expected
  302. * to longjmp out, which means accepting the cost of using setjmp.
  303. *
  304. * It would perhaps be reasonable to write the dispatch code as a big
  305. * macro so that the versions for plus, times etc could all be kept
  306. * in step - I have not done that (a) because the macro would have been
  307. * bigger than I like macros to be (b) it would have involved token-
  308. * splicing (or VERY many parameters) to generate the names of the
  309. * separate type-specific procedures and (c) doing it by hand allows me
  310. * total flexibility about coding various cases in-line.
  311. */
  312. #ifdef COMMON
  313. static Lisp_Object plusis(Lisp_Object a, Lisp_Object b)
  314. {
  315. Float_union bb;
  316. bb.i = b - TAG_SFLOAT;
  317. bb.f = (float)((float)int_of_fixnum(a) + bb.f);
  318. return (bb.i & ~(int32)0xf) + TAG_SFLOAT;
  319. }
  320. #endif
  321. /*
  322. * Bignums are represented as vectors where the most significant 32-bit
  323. * digit is treated as signed, and the remaining ones are unsigned.
  324. */
  325. static Lisp_Object plusib(Lisp_Object a, Lisp_Object b)
  326. /*
  327. * Add a fixnum to a bignum, returning a result as a fixnum or bignum
  328. * depending on its size. This seems much nastier than one would have
  329. * hoped.
  330. */
  331. {
  332. int32 len = bignum_length(b), i, sign = int_of_fixnum(a), s;
  333. Lisp_Object c, nil;
  334. len = (len >> 2) - 1;
  335. if (len == 1)
  336. { int32 t;
  337. /*
  338. * Partly because it will be a common case and partly because it has
  339. * various special cases I have special purpose code to cope with
  340. * adding a fixnum to a one-word bignum.
  341. */
  342. s = (int32)bignum_digits(b)[0] + sign;
  343. t = s + s;
  344. if (top_bit_set(s ^ t)) /* needs to turn into two-word bignum */
  345. { c = getvector(TAG_NUMBERS, TYPE_BIGNUM, 12);
  346. errexit();
  347. if (top_bit_set(s))
  348. { bignum_digits(c)[0] = clear_top_bit(s);
  349. bignum_digits(c)[1] = (unsigned32)(-1);
  350. }
  351. else
  352. { bignum_digits(c)[0] = s;
  353. bignum_digits(c)[1] = 0;
  354. }
  355. bignum_digits(c)[2] = 0; /* set padding word to zero to be tidy */
  356. return c;
  357. }
  358. t = s & fix_mask; /* Will it fit as a fixnum? */
  359. if (t == 0 || t == fix_mask) return fixnum_of_int(s);
  360. /* here the result is a one-word bignum */
  361. c = getvector(TAG_NUMBERS, TYPE_BIGNUM, 8);
  362. errexit();
  363. bignum_digits(c)[0] = s;
  364. return c;
  365. }
  366. /*
  367. * Now, after all the silly cases have been handled, I have a calculation
  368. * which seems set to give a multi-word result. The result here can at
  369. * least never shrink to a fixnum since subtracting a fixnum can at
  370. * most shrink the length of a number by one word. I omit the stack-
  371. * check here in the hope that code here never nests enough for trouble.
  372. */
  373. push(b);
  374. c = getvector(TAG_NUMBERS, TYPE_BIGNUM, 4+(len<<2));
  375. pop(b);
  376. errexit();
  377. s = bignum_digits(b)[0] + clear_top_bit(sign);
  378. bignum_digits(c)[0] = clear_top_bit(s);
  379. if (sign >= 0) sign = 0; else sign = 0x7fffffff; /* extend the sign */
  380. len--;
  381. for (i=1; i<len; i++)
  382. { s = bignum_digits(b)[i] + sign + top_bit(s);
  383. bignum_digits(c)[i] = clear_top_bit(s);
  384. }
  385. /* Now just the most significant digit remains to be processed */
  386. if (sign != 0) sign = -1;
  387. { s = bignum_digits(b)[i] + sign + top_bit(s);
  388. if (!signed_overflow(s)) /* did it overflow? */
  389. {
  390. /*
  391. * Here the most significant digit did not produce an overflow, but maybe
  392. * what we actually had was some cancellation and the MSD is now zero
  393. * or -1, so that the number should shrink...
  394. */
  395. if ((s == 0 && (bignum_digits(c)[i-1] & 0x40000000) == 0) ||
  396. (s == -1 && (bignum_digits(c)[i-1] & 0x40000000) != 0))
  397. { /* shrink the number */
  398. numhdr(c) -= pack_hdrlength(1L);
  399. if (s == -1) bignum_digits(c)[i-1] |= ~0x7fffffff;
  400. /*
  401. * Now sometimes the shrinkage will leave a padding word, sometimes it
  402. * will really allow me to save space.
  403. */
  404. if ((i & 1) == 0)
  405. { bignum_digits(c)[i] = 0; /* leave the unused word tidy */
  406. return c;
  407. }
  408. /*
  409. * Having shrunk the number I am leaving a doubleword of unallocated space
  410. * in the heap. Dump a header word into it to make it look like an
  411. * 8-byte bignum since that will allow the garbage collector to handle it.
  412. * It I left it containing arbitrary junk I could wreck myself.
  413. */
  414. bignum_digits(c)[i] = make_bighdr(2L);
  415. return c;
  416. }
  417. bignum_digits(c)[i] = s; /* length unchanged */
  418. return c;
  419. }
  420. /*
  421. * Here the result is one word longer than the input-bignum.
  422. * Once again SOMTIMES this will not involve allocating more store,
  423. * but just encroaching into the previously unused word that was padding
  424. * things out to a multiple of 8 bytes.
  425. */
  426. if ((i & 1) == 1)
  427. { bignum_digits(c)[i++] = clear_top_bit(s);
  428. bignum_digits(c)[i] = top_bit_set(s) ? -1 : 0;
  429. numhdr(c) += pack_hdrlength(1L);
  430. return c;
  431. }
  432. push(c);
  433. b = getvector(TAG_NUMBERS, TYPE_BIGNUM, 12+(len<<2));
  434. pop(c);
  435. errexit();
  436. for (i=0; i<=len; i++)
  437. bignum_digits(b)[i] = bignum_digits(c)[i];
  438. bignum_digits(b)[i++] = clear_top_bit(s);
  439. bignum_digits(b)[i] = top_bit_set(s) ? -1 : 0;
  440. return b;
  441. }
  442. }
  443. #ifdef COMMON
  444. static Lisp_Object plusir(Lisp_Object a, Lisp_Object b)
  445. /*
  446. * fixnum and ratio, but also valid for bignum and ratio.
  447. * Note that if the inputs were in lowest terms there is no need for
  448. * and GCD calculations here.
  449. */
  450. {
  451. Lisp_Object nil;
  452. push(b);
  453. a = times2(a, denominator(b));
  454. nil = C_nil;
  455. if (!exception_pending()) a = plus2(a, numerator(stack[0]));
  456. pop(b);
  457. errexit();
  458. return make_ratio(a, denominator(b));
  459. }
  460. static Lisp_Object plusic(Lisp_Object a, Lisp_Object b)
  461. /*
  462. * real of any sort plus complex.
  463. */
  464. {
  465. Lisp_Object nil;
  466. push(b);
  467. a = plus2(a, real_part(b));
  468. pop(b);
  469. errexit();
  470. /*
  471. * make_complex() takes responsibility for mapping #C(n 0) onto n
  472. */
  473. return make_complex(a, imag_part(b));
  474. }
  475. #endif
  476. static Lisp_Object plusif(Lisp_Object a, Lisp_Object b)
  477. /*
  478. * Fixnum plus boxed-float.
  479. */
  480. {
  481. double d = (double)int_of_fixnum(a) + float_of_number(b);
  482. return make_boxfloat(d, type_of_header(flthdr(b)));
  483. }
  484. #ifdef COMMON
  485. #define plussi(a, b) plusis(b, a)
  486. #define plussb(a, b) plusbs(b, a)
  487. #define plussr(a, b) plusrs(b, a)
  488. #define plussc(a, b) plusic(a, b)
  489. #endif
  490. static Lisp_Object plussf(Lisp_Object a, Lisp_Object b)
  491. /*
  492. * This can be used for any rational value plus a boxed-float. plusif()
  493. * is separated just for (minor) efficiency reasons.
  494. */
  495. {
  496. double d = float_of_number(a) + float_of_number(b);
  497. return make_boxfloat(d, type_of_header(flthdr(b)));
  498. }
  499. #define plusbi(a, b) plusib(b, a)
  500. #ifdef COMMON
  501. static Lisp_Object plusbs(Lisp_Object a, Lisp_Object b)
  502. {
  503. double d = float_of_number(a) + float_of_number(b);
  504. return make_sfloat(d);
  505. }
  506. #endif
  507. Lisp_Object lengthen_by_one_bit(Lisp_Object a, int32 msd)
  508. /*
  509. * (a) is a bignum, and arithmetic on it has (just) caused overflow
  510. * in its top word - I just need to stick on another word. (msd) is the
  511. * current top word, and its sign will be used to decide on the value
  512. * that must be appended.
  513. */
  514. {
  515. int32 len = bignum_length(a);
  516. /*
  517. * Sometimes I need to allocate a new vector and copy data across into it
  518. */
  519. if ((len & 4) == 0)
  520. { Lisp_Object b, nil;
  521. int32 i;
  522. push(a);
  523. b = getvector(TAG_NUMBERS, TYPE_BIGNUM, len+4);
  524. pop(a);
  525. errexit();
  526. len = (len >> 2) - 1;
  527. for (i=0; i<len; i++)
  528. bignum_digits(b)[i] = clear_top_bit(bignum_digits(a)[i]);
  529. bignum_digits(b)[i] = top_bit_set(msd) ? -1 : 0;
  530. bignum_digits(b)[i+1] = 0;
  531. return b;
  532. }
  533. else
  534. /*
  535. * .. whereas sometimes I have a spare word already available.
  536. */
  537. { numhdr(a) += pack_hdrlength(1L);
  538. len = (len >> 2) - 1;
  539. bignum_digits(a)[len-1] = clear_top_bit(bignum_digits(a)[len-1]);
  540. bignum_digits(a)[len] = top_bit_set(msd) ? -1 : 0;
  541. return a;
  542. }
  543. }
  544. static Lisp_Object plusbb(Lisp_Object a, Lisp_Object b)
  545. /*
  546. * add two bignums.
  547. */
  548. {
  549. int32 la = bignum_length(a),
  550. lb = bignum_length(b),
  551. i, s, carry;
  552. Lisp_Object c, nil;
  553. if (la < lb) /* maybe swap order of args */
  554. { Lisp_Object t = a;
  555. int32 t1;
  556. a = b; b = t;
  557. t1 = la; la = lb; lb = t1;
  558. }
  559. /*
  560. * now (a) is AT LEAST as long as b. I have special case code for
  561. * when both args are single-word bignums, since I expect that to be
  562. * an especially common case.
  563. */
  564. if (la == 8) /* and hence b also has only 1 digit */
  565. { int32 va = bignum_digits(a)[0],
  566. vb = bignum_digits(b)[0],
  567. vc = va + vb;
  568. if (signed_overflow(vc)) /* we have a 2-word bignum result */
  569. { Lisp_Object w = getvector(TAG_NUMBERS, TYPE_BIGNUM, 12);
  570. errexit();
  571. bignum_digits(w)[0] = clear_top_bit(vc);
  572. bignum_digits(w)[1] = top_bit_set(vc) ? -1 : 0;
  573. bignum_digits(w)[2] = 0;
  574. return w;
  575. }
  576. /*
  577. * here the result fits into one word - maybe it will squash down into
  578. * a fixnum?
  579. */
  580. else
  581. { vb = vc & fix_mask;
  582. if (vb == 0 || vb == fix_mask) return fixnum_of_int(vc);
  583. else return make_one_word_bignum(vc);
  584. }
  585. }
  586. push2(a, b);
  587. c = getvector(TAG_NUMBERS, TYPE_BIGNUM, la);
  588. pop2(b, a);
  589. errexit();
  590. la = (la >> 2) - 2;
  591. lb = (lb >> 2) - 2;
  592. carry = 0;
  593. /*
  594. * Add all but the top digit of b
  595. */
  596. for (i=0; i<lb; i++)
  597. { carry = bignum_digits(a)[i] + bignum_digits(b)[i] + top_bit(carry);
  598. bignum_digits(c)[i] = clear_top_bit(carry);
  599. }
  600. if (la == lb) s = bignum_digits(b)[i];
  601. else
  602. /*
  603. * If a is strictly longer than b I sign extend b here and add in as many
  604. * copies of 0 or -1 as needbe to get up to the length of a.
  605. */
  606. { s = bignum_digits(b)[i];
  607. carry = bignum_digits(a)[i] + clear_top_bit(s) + top_bit(carry);
  608. bignum_digits(c)[i] = clear_top_bit(carry);
  609. if (s < 0) s = -1; else s = 0;
  610. for (i++; i<la; i++)
  611. { carry = bignum_digits(a)[i] + clear_top_bit(s) + top_bit(carry);
  612. bignum_digits(c)[i] = clear_top_bit(carry);
  613. }
  614. }
  615. /*
  616. * the most significant digit is added using signed arithmetic so that I
  617. * can tell if it overflowed.
  618. */
  619. carry = bignum_digits(a)[i] + s + top_bit(carry);
  620. if (!signed_overflow(carry))
  621. {
  622. /*
  623. * Here the number has not expanded - but it may be shrinking, and it can
  624. * shrink by any number of words, all the way down to a fixnum maybe. Note
  625. * that I started with at least a 2-word bignum here.
  626. */
  627. int32 msd;
  628. bignum_digits(c)[i] = carry;
  629. if (carry == 0)
  630. { int32 j = i-1;
  631. while ((msd = bignum_digits(c)[j]) == 0 && j > 0) j--;
  632. /*
  633. * ... but I may need a zero word on the front if the next word down
  634. * has its top bit set... (top of 31 bits, that is)
  635. */
  636. if ((msd & 0x40000000) != 0)
  637. { j++;
  638. if (i == j) return c;
  639. }
  640. if (j == 0)
  641. { int32 s = bignum_digits(c)[0];
  642. if ((s & fix_mask) == 0) return fixnum_of_int(s);
  643. }
  644. /*
  645. * If I am shrinking by one word and had an even length to start with
  646. * I do not have to mess about so much.
  647. */
  648. if (j == i-1 && (i & 1) == 0)
  649. { numhdr(c) -= pack_hdrlength(1L);
  650. return c;
  651. }
  652. numhdr(c) -= pack_hdrlength(i - j);
  653. i = (i+1) | 1;
  654. j = (j+1) | 1; /* Round up to odd index */
  655. /*
  656. * I forge a header word to allow the garbage collector to skip over
  657. * (and in due course reclaim) the space that turned out not to be needed.
  658. */
  659. bignum_digits(c)[j] = make_bighdr(i - j);
  660. return c;
  661. }
  662. /*
  663. * Now do all the same sorts of things but this time for negative numbers.
  664. */
  665. else if (carry == -1)
  666. { int32 j = i-1;
  667. msd = carry; /* in case j = 0 */
  668. while ((msd = bignum_digits(c)[j]) == 0x7fffffff && j > 0) j--;
  669. if ((msd & 0x40000000) == 0)
  670. { j++;
  671. if (i == j) return c;
  672. }
  673. if (j == 0)
  674. { int32 s = bignum_digits(c)[0] | ~0x7fffffff;
  675. if ((s & fix_mask) == fix_mask) return fixnum_of_int(s);
  676. }
  677. if (j == i-1 && (i & 1) == 0)
  678. { bignum_digits(c)[i] = 0;
  679. bignum_digits(c)[i-1] |= ~0x7fffffff;
  680. numhdr(c) -= pack_hdrlength(1);
  681. return c;
  682. }
  683. numhdr(c) -= pack_hdrlength(i - j);
  684. bignum_digits(c)[j+1] = 0;
  685. bignum_digits(c)[j] |= ~0x7fffffff;
  686. i = (i+1) | 1;
  687. j = (j+1) | 1; /* Round up to odd index */
  688. bignum_digits(c)[j] = make_bighdr(i - j);
  689. return c;
  690. }
  691. return c;
  692. }
  693. else
  694. { bignum_digits(c)[i] = carry;
  695. return lengthen_by_one_bit(c, carry);
  696. }
  697. }
  698. #ifdef COMMON
  699. #define plusbr(a, b) plusir(a, b)
  700. #define plusbc(a, b) plusic(a, b)
  701. #endif
  702. #define plusbf(a, b) plussf(a, b)
  703. #ifdef COMMON
  704. #define plusri(a, b) plusir(b, a)
  705. #define plusrs(a, b) plusbs(a, b)
  706. #define plusrb(a, b) plusri(a, b)
  707. static Lisp_Object plusrr(Lisp_Object a, Lisp_Object b)
  708. /*
  709. * Adding two ratios involves some effort to keep the result in
  710. * lowest terms.
  711. */
  712. {
  713. Lisp_Object nil = C_nil;
  714. Lisp_Object na = numerator(a), nb = numerator(b);
  715. Lisp_Object da = denominator(a), db = denominator(b);
  716. Lisp_Object w = nil;
  717. push5(na, nb, da, db, nil);
  718. #define g stack[0]
  719. #define db stack[-1]
  720. #define da stack[-2]
  721. #define nb stack[-3]
  722. #define na stack[-4]
  723. g = gcd(da, db);
  724. nil = C_nil;
  725. if (exception_pending()) goto fail;
  726. /*
  727. * all the calls to quot2() in this procedure are expected - nay required -
  728. * to give exact integer quotients.
  729. */
  730. db = quot2(db, g);
  731. nil = C_nil;
  732. if (exception_pending()) goto fail;
  733. g = quot2(da, g);
  734. nil = C_nil;
  735. if (exception_pending()) goto fail;
  736. na = times2(na, db);
  737. nil = C_nil;
  738. if (exception_pending()) goto fail;
  739. nb = times2(nb, g);
  740. nil = C_nil;
  741. if (exception_pending()) goto fail;
  742. na = plus2(na, nb);
  743. nil = C_nil;
  744. if (exception_pending()) goto fail;
  745. da = times2(da, db);
  746. nil = C_nil;
  747. if (exception_pending()) goto fail;
  748. g = gcd(na, da);
  749. nil = C_nil;
  750. if (exception_pending()) goto fail;
  751. na = quot2(na, g);
  752. nil = C_nil;
  753. if (exception_pending()) goto fail;
  754. da = quot2(da, g);
  755. nil = C_nil;
  756. if (exception_pending()) goto fail;
  757. w = make_ratio(na, da);
  758. /*
  759. * All the goto statements and the label seem a fair way of expressing
  760. * the common action that has to be taken if an error or interrupt is
  761. * detected during any of the intermediate steps here. Anyone who
  762. * objects can change it if they really want...
  763. */
  764. fail:
  765. popv(5);
  766. return w;
  767. #undef na
  768. #undef nb
  769. #undef da
  770. #undef db
  771. #undef g
  772. }
  773. #define plusrc(a, b) plusic(a, b)
  774. #define plusrf(a, b) plussf(a, b)
  775. #define plusci(a, b) plusic(b, a)
  776. #define pluscs(a, b) plussc(b, a)
  777. #define pluscb(a, b) plusbc(b, a)
  778. #define pluscr(a, b) plusrc(b, a)
  779. static Lisp_Object pluscc(Lisp_Object a, Lisp_Object b)
  780. /*
  781. * Add complex values.
  782. */
  783. {
  784. Lisp_Object c, nil;
  785. push2(a, b);
  786. c = plus2(imag_part(a), imag_part(b));
  787. pop2(b, a);
  788. errexit();
  789. a = plus2(real_part(a), real_part(b));
  790. errexit();
  791. return make_complex(a, c);
  792. }
  793. #define pluscf(a, b) plusfc(b, a)
  794. #endif
  795. #define plusfi(a, b) plusif(b, a)
  796. #ifdef COMMON
  797. #define plusfs(a, b) plussf(b, a)
  798. #endif
  799. #define plusfb(a, b) plusbf(b, a)
  800. #ifdef COMMON
  801. #define plusfr(a, b) plusrf(b, a)
  802. #define plusfc(a, b) plusic(a, b)
  803. #endif
  804. static Lisp_Object plusff(Lisp_Object a, Lisp_Object b)
  805. /*
  806. * Add two boxed floats - the type of the result must match the
  807. * longer of the types of the arguments, hence the extra
  808. * messing about.
  809. */
  810. {
  811. #ifdef COMMON
  812. int32 ha = type_of_header(flthdr(a)), hb = type_of_header(flthdr(b));
  813. #endif
  814. double d;
  815. /*
  816. * This is written as a declaration followed by a separate assignment to
  817. * d because I hit a compiler bug on a VAX once otherwise.
  818. */
  819. d = float_of_number(a) + float_of_number(b);
  820. #ifdef COMMON
  821. if (ha == TYPE_LONG_FLOAT || hb == TYPE_LONG_FLOAT)
  822. ha = TYPE_LONG_FLOAT;
  823. else if (ha == TYPE_DOUBLE_FLOAT || hb == TYPE_DOUBLE_FLOAT)
  824. ha = TYPE_DOUBLE_FLOAT;
  825. else ha = TYPE_SINGLE_FLOAT;
  826. return make_boxfloat(d, ha);
  827. #else
  828. return make_boxfloat(d, TYPE_DOUBLE_FLOAT);
  829. #endif
  830. }
  831. /*
  832. * and now for the dispatch code...
  833. */
  834. /*
  835. * The following verifies that a number is properly formatted - a
  836. * fixnum if small enough or a decently normalised bignum. For use when
  837. * there is suspicion of a bug wrt such matters. Call is
  838. * validate_number("msg", numberToCheck, nX, nY)
  839. * where nX and nY must be numbers and are shown in any
  840. * diagnostic.
  841. */
  842. void validate_number(char *s, Lisp_Object a, Lisp_Object b, Lisp_Object c)
  843. {
  844. int32 la, w, msd;
  845. if (!is_numbers(a)) return;
  846. la = (length_of_header(numhdr(a))>>2)-2;
  847. if (la < 0)
  848. { trace_printf("%s: number with no digits (%.8x)\n", s, numhdr(a));
  849. if (is_number(b)) prin_to_trace(b), trace_printf("\n");
  850. if (is_number(c)) prin_to_trace(c), trace_printf("\n");
  851. my_exit(EXIT_FAILURE);
  852. }
  853. if (la == 0)
  854. { msd = bignum_digits(a)[0];
  855. w = msd & fix_mask;
  856. if (w == 0 || w == fix_mask)
  857. { trace_printf("%s: %.8x should be fixnum\n", s, msd);
  858. if (is_number(b)) prin_to_trace(b), trace_printf("\n");
  859. if (is_number(c)) prin_to_trace(c), trace_printf("\n");
  860. my_exit(EXIT_FAILURE);
  861. }
  862. if (signed_overflow(msd))
  863. { trace_printf("%s: %.8x should be two-word\n", s, msd);
  864. if (is_number(b)) prin_to_trace(b), trace_printf("\n");
  865. if (is_number(c)) prin_to_trace(c), trace_printf("\n");
  866. my_exit(EXIT_FAILURE);
  867. }
  868. return;
  869. }
  870. msd = bignum_digits(a)[la];
  871. if (signed_overflow(msd))
  872. { trace_printf("%s: %.8x should be longer\n", s, msd);
  873. if (is_number(b)) prin_to_trace(b), trace_printf("\n");
  874. if (is_number(c)) prin_to_trace(c), trace_printf("\n");
  875. my_exit(EXIT_FAILURE);
  876. }
  877. if (msd == 0 && ((msd = bignum_digits(a)[la-1]) & 0x40000000) == 0)
  878. { trace_printf("%s: 0: %.8x should be shorter\n", s, msd);
  879. if (is_number(b)) prin_to_trace(b), trace_printf("\n");
  880. if (is_number(c)) prin_to_trace(c), trace_printf("\n");
  881. my_exit(EXIT_FAILURE);
  882. }
  883. if (msd == -1 && ((msd = bignum_digits(a)[la-1]) & 0x40000000) != 0)
  884. { trace_printf("%s: -1: %.8x should be shorter\n", s, msd);
  885. if (is_number(b)) prin_to_trace(b), trace_printf("\n");
  886. if (is_number(c)) prin_to_trace(c), trace_printf("\n");
  887. my_exit(EXIT_FAILURE);
  888. }
  889. }
  890. Lisp_Object plus2(Lisp_Object a, Lisp_Object b)
  891. /*
  892. * I probably want to change the specification of plus2 so that the fixnum +
  893. * fixnum case is always expected to be done before the main body of the code
  894. * is entered. Well maybe even if I do that it then costs very little to
  895. * include the fixnum code here as well, so I will not delete it.
  896. */
  897. {
  898. switch ((int)a & TAG_BITS)
  899. {
  900. case TAG_FIXNUM:
  901. switch ((int)b & TAG_BITS)
  902. {
  903. case TAG_FIXNUM:
  904. /*
  905. * This is where fixnum + fixnum arithmetic happens - the case I most want to
  906. * make efficient.
  907. */
  908. { int32 r = int_of_fixnum(a) + int_of_fixnum(b);
  909. int32 t = r & fix_mask;
  910. if (t == 0 || t == fix_mask) return fixnum_of_int(r);
  911. else return make_one_word_bignum(r);
  912. }
  913. #ifdef COMMON
  914. case TAG_SFLOAT:
  915. return plusis(a, b);
  916. #endif
  917. case TAG_NUMBERS:
  918. { int32 hb = type_of_header(numhdr(b));
  919. switch (hb)
  920. {
  921. case TYPE_BIGNUM:
  922. return plusib(a, b);
  923. #ifdef COMMON
  924. case TYPE_RATNUM:
  925. return plusir(a, b);
  926. case TYPE_COMPLEX_NUM:
  927. return plusic(a, b);
  928. #endif
  929. default:
  930. return aerror1("bad arg for plus", b);
  931. }
  932. }
  933. case TAG_BOXFLOAT:
  934. return plusif(a, b);
  935. default:
  936. return aerror1("bad arg for plus", b);
  937. }
  938. #ifdef COMMON
  939. case TAG_SFLOAT:
  940. switch (b & TAG_BITS)
  941. {
  942. case TAG_FIXNUM:
  943. return plussi(a, b);
  944. case TAG_SFLOAT:
  945. { Float_union aa, bb;
  946. aa.i = a - TAG_SFLOAT;
  947. bb.i = b - TAG_SFLOAT;
  948. aa.f = (float)(aa.f + bb.f);
  949. return (aa.i & ~(int32)0xf) + TAG_SFLOAT;
  950. }
  951. case TAG_NUMBERS:
  952. { int32 hb = type_of_header(numhdr(b));
  953. switch (hb)
  954. {
  955. case TYPE_BIGNUM:
  956. return plussb(a, b);
  957. case TYPE_RATNUM:
  958. return plussr(a, b);
  959. case TYPE_COMPLEX_NUM:
  960. return plussc(a, b);
  961. default:
  962. return aerror1("bad arg for plus", b);
  963. }
  964. }
  965. case TAG_BOXFLOAT:
  966. return plussf(a, b);
  967. default:
  968. return aerror1("bad arg for plus", b);
  969. }
  970. #endif
  971. case TAG_NUMBERS:
  972. { int32 ha = type_of_header(numhdr(a));
  973. switch (ha)
  974. {
  975. case TYPE_BIGNUM:
  976. switch ((int)b & TAG_BITS)
  977. {
  978. case TAG_FIXNUM:
  979. return plusbi(a, b);
  980. #ifdef COMMON
  981. case TAG_SFLOAT:
  982. return plusbs(a, b);
  983. #endif
  984. case TAG_NUMBERS:
  985. { int32 hb = type_of_header(numhdr(b));
  986. switch (hb)
  987. {
  988. case TYPE_BIGNUM:
  989. return plusbb(a, b);
  990. #ifdef COMMON
  991. case TYPE_RATNUM:
  992. return plusbr(a, b);
  993. case TYPE_COMPLEX_NUM:
  994. return plusbc(a, b);
  995. #endif
  996. default:
  997. return aerror1("bad arg for plus", b);
  998. }
  999. }
  1000. case TAG_BOXFLOAT:
  1001. return plusbf(a, b);
  1002. default:
  1003. return aerror1("bad arg for plus", b);
  1004. }
  1005. #ifdef COMMON
  1006. case TYPE_RATNUM:
  1007. switch (b & TAG_BITS)
  1008. {
  1009. case TAG_FIXNUM:
  1010. return plusri(a, b);
  1011. case TAG_SFLOAT:
  1012. return plusrs(a, b);
  1013. case TAG_NUMBERS:
  1014. { int32 hb = type_of_header(numhdr(b));
  1015. switch (hb)
  1016. {
  1017. case TYPE_BIGNUM:
  1018. return plusrb(a, b);
  1019. case TYPE_RATNUM:
  1020. return plusrr(a, b);
  1021. case TYPE_COMPLEX_NUM:
  1022. return plusrc(a, b);
  1023. default:
  1024. return aerror1("bad arg for plus", b);
  1025. }
  1026. }
  1027. case TAG_BOXFLOAT:
  1028. return plusrf(a, b);
  1029. default:
  1030. return aerror1("bad arg for plus", b);
  1031. }
  1032. case TYPE_COMPLEX_NUM:
  1033. switch (b & TAG_BITS)
  1034. {
  1035. case TAG_FIXNUM:
  1036. return plusci(a, b);
  1037. case TAG_SFLOAT:
  1038. return pluscs(a, b);
  1039. case TAG_NUMBERS:
  1040. { int32 hb = type_of_header(numhdr(b));
  1041. switch (hb)
  1042. {
  1043. case TYPE_BIGNUM:
  1044. return pluscb(a, b);
  1045. case TYPE_RATNUM:
  1046. return pluscr(a, b);
  1047. case TYPE_COMPLEX_NUM:
  1048. return pluscc(a, b);
  1049. default:
  1050. return aerror1("bad arg for plus", b);
  1051. }
  1052. }
  1053. case TAG_BOXFLOAT:
  1054. return pluscf(a, b);
  1055. default:
  1056. return aerror1("bad arg for plus", b);
  1057. }
  1058. #endif
  1059. default: return aerror1("bad arg for plus", a);
  1060. }
  1061. }
  1062. case TAG_BOXFLOAT:
  1063. switch ((int)b & TAG_BITS)
  1064. {
  1065. case TAG_FIXNUM:
  1066. return plusfi(a, b);
  1067. #ifdef COMMON
  1068. case TAG_SFLOAT:
  1069. return plusfs(a, b);
  1070. #endif
  1071. case TAG_NUMBERS:
  1072. { int32 hb = type_of_header(numhdr(b));
  1073. switch (hb)
  1074. {
  1075. case TYPE_BIGNUM:
  1076. return plusfb(a, b);
  1077. #ifdef COMMON
  1078. case TYPE_RATNUM:
  1079. return plusfr(a, b);
  1080. case TYPE_COMPLEX_NUM:
  1081. return plusfc(a, b);
  1082. #endif
  1083. default:
  1084. return aerror1("bad arg for plus", b);
  1085. }
  1086. }
  1087. case TAG_BOXFLOAT:
  1088. return plusff(a, b);
  1089. default:
  1090. return aerror1("bad arg for plus", b);
  1091. }
  1092. default:
  1093. return aerror1("bad arg for plus", a);
  1094. }
  1095. }
  1096. Lisp_Object difference2(Lisp_Object a, Lisp_Object b)
  1097. {
  1098. Lisp_Object nil;
  1099. switch ((int)b & TAG_BITS)
  1100. {
  1101. case TAG_FIXNUM:
  1102. if (is_fixnum(a))
  1103. {
  1104. int32 r = int_of_fixnum(a) - int_of_fixnum(b);
  1105. int32 t = r & fix_mask;
  1106. if (t == 0 || t == fix_mask) return fixnum_of_int(r);
  1107. else return make_one_word_bignum(r);
  1108. }
  1109. else if (b != ~0x7ffffffe) return plus2(a, 2*TAG_FIXNUM-b);
  1110. else
  1111. { push(a);
  1112. b = make_one_word_bignum(-int_of_fixnum(b));
  1113. break;
  1114. }
  1115. case TAG_NUMBERS:
  1116. push(a);
  1117. if (type_of_header(numhdr(b)) == TYPE_BIGNUM) b = negateb(b);
  1118. else b = negate(b);
  1119. break;
  1120. case TAG_BOXFLOAT:
  1121. default:
  1122. push(a);
  1123. b = negate(b);
  1124. break;
  1125. }
  1126. pop(a);
  1127. errexit();
  1128. return plus2(a, b);
  1129. }
  1130. Lisp_Object add1(Lisp_Object p)
  1131. /*
  1132. * Increment a number. Short cut when the number is a fixnum, otherwise
  1133. * just hand over to the general addition code.
  1134. */
  1135. {
  1136. if (is_fixnum(p))
  1137. { unsigned32 r = (int32)p + 0x10;
  1138. /* fixnums have data shifted left 4 bits */
  1139. if (r == ~0x7ffffffe) /* The ONLY possible overflow case here */
  1140. return make_one_word_bignum(1 + int_of_fixnum(p));
  1141. else return (Lisp_Object)r;
  1142. }
  1143. else return plus2(p, fixnum_of_int(1));
  1144. }
  1145. Lisp_Object sub1(Lisp_Object p)
  1146. /*
  1147. * Decrement a number. Short cut when the number is a fixnum, otherwise
  1148. * just hand over to the general addition code.
  1149. */
  1150. {
  1151. if (is_fixnum(p))
  1152. { if (p == ~0x7ffffffe) /* The ONLY possible overflow case here */
  1153. return make_one_word_bignum(int_of_fixnum(p) - 1);
  1154. else return (Lisp_Object)(p - 0x10);
  1155. }
  1156. else return plus2(p, fixnum_of_int(-1));
  1157. }
  1158. /* end of arith01.c */