arith08.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380
  1. /* arith08.c Copyright (C) 1990-95 Codemist Ltd */
  2. /*
  3. * Arithmetic functions.
  4. */
  5. /* Signature: 02ccc991 07-Mar-2000 */
  6. #include <stdarg.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <math.h>
  10. #include <float.h>
  11. #include "machine.h"
  12. #include "tags.h"
  13. #include "cslerror.h"
  14. #include "externs.h"
  15. #include "arith.h"
  16. #include "entries.h"
  17. #ifdef TIMEOUT
  18. #include "timeout.h"
  19. #endif
  20. #ifdef COMMON
  21. static Lisp_Object MS_CDECL Lboole(Lisp_Object nil, int nargs, ...)
  22. {
  23. Lisp_Object r, op, a, b;
  24. va_list aa;
  25. argcheck(nargs, 3, "boole");
  26. va_start(aa, nargs);
  27. op = va_arg(aa, Lisp_Object);
  28. a = va_arg(aa, Lisp_Object);
  29. b = va_arg(aa, Lisp_Object);
  30. va_end(aa);
  31. switch (op)
  32. {
  33. case fixnum_of_int(boole_clr):
  34. return onevalue(fixnum_of_int(0));
  35. case fixnum_of_int(boole_and):
  36. r = logand2(a, b);
  37. break;
  38. case fixnum_of_int(boole_andc2):
  39. push(a);
  40. b = lognot(b);
  41. pop(a);
  42. errexit();
  43. r = logand2(a, b);
  44. break;
  45. case fixnum_of_int(boole_1):
  46. return onevalue(a);
  47. case fixnum_of_int(boole_andc1):
  48. push(b);
  49. a = lognot(a);
  50. pop(b);
  51. errexit();
  52. r = logand2(a, b);
  53. break;
  54. case fixnum_of_int(boole_2):
  55. return onevalue(b);
  56. case fixnum_of_int(boole_xor):
  57. r = logxor2(a, b);
  58. break;
  59. case fixnum_of_int(boole_ior):
  60. r = logior2(a, b);
  61. break;
  62. case fixnum_of_int(boole_nor):
  63. a = logior2(a, b);
  64. errexit();
  65. r = lognot(a);
  66. break;
  67. case fixnum_of_int(boole_eqv):
  68. r = logeqv2(a, b);
  69. break;
  70. case fixnum_of_int(boole_c2):
  71. r = lognot(b);
  72. break;
  73. case fixnum_of_int(boole_orc2):
  74. b = lognot(b);
  75. errexit();
  76. r = logior2(a, b);
  77. break;
  78. case fixnum_of_int(boole_c1):
  79. r = lognot(a);
  80. break;
  81. case fixnum_of_int(boole_orc1):
  82. push(b);
  83. a = lognot(a);
  84. pop(b);
  85. errexit();
  86. r = logior2(a, b);
  87. break;
  88. case fixnum_of_int(boole_nand):
  89. a = logand2(a, b);
  90. errexit();
  91. r = lognot(a);
  92. break;
  93. case fixnum_of_int(boole_set):
  94. return onevalue(fixnum_of_int(-1));
  95. default:
  96. return aerror1("bad arg for boole", op);
  97. }
  98. errexit();
  99. return onevalue(r);
  100. }
  101. static Lisp_Object Lbyte(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  102. {
  103. a = cons(a, b);
  104. errexit();
  105. return onevalue(a);
  106. }
  107. static Lisp_Object Lbyte_position(Lisp_Object nil, Lisp_Object a)
  108. {
  109. if (!consp(a)) return aerror1("byte-position", a);
  110. else return onevalue(qcdr(a));
  111. }
  112. static Lisp_Object Lbyte_size(Lisp_Object nil, Lisp_Object a)
  113. {
  114. if (!consp(a)) return aerror1("byte-size", a);
  115. else return onevalue(qcar(a));
  116. }
  117. static Lisp_Object Lcomplex_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  118. {
  119. /* /* Need to coerce a and b to the same type here... */
  120. a = make_complex(a, b);
  121. errexit();
  122. return onevalue(a);
  123. }
  124. static Lisp_Object Lcomplex_1(Lisp_Object nil, Lisp_Object a)
  125. {
  126. /* /* Need to make zero of same type as a */
  127. a = make_complex(a, fixnum_of_int(0));
  128. errexit();
  129. return onevalue(a);
  130. }
  131. static Lisp_Object Lconjugate(Lisp_Object nil, Lisp_Object a)
  132. {
  133. if (!is_number(a)) return aerror1("conjugate", a);
  134. if (is_numbers(a) && is_complex(a))
  135. { Lisp_Object r = real_part(a),
  136. i = imag_part(a);
  137. push(r);
  138. i = negate(i);
  139. pop(r);
  140. errexit();
  141. a = make_complex(r, i);
  142. errexit();
  143. return onevalue(a);
  144. }
  145. else return onevalue(a);
  146. }
  147. static Lisp_Object Ldecode_float(Lisp_Object nil, Lisp_Object a)
  148. {
  149. double d = float_of_number(a), neg = 1.0;
  150. int x;
  151. Lisp_Object sign;
  152. if (!is_float(a)) return aerror("decode-float");
  153. if (d < 0.0) d = -d, neg = -1.0;
  154. if (d == 0.0) x = 0;
  155. else
  156. { d = frexp(d, &x);
  157. if (d == 1.0) d = 0.5, x++;
  158. }
  159. if (is_sfloat(a)) sign = make_sfloat(neg);
  160. else sign = make_boxfloat(neg, type_of_header(flthdr(a)));
  161. errexit();
  162. push(sign);
  163. if (is_sfloat(a)) a = make_sfloat(d);
  164. else a = make_boxfloat(d, type_of_header(flthdr(a)));
  165. pop(sign);
  166. errexit();
  167. mv_2 = fixnum_of_int(x);
  168. mv_3 = sign;
  169. return nvalues(a, 3);
  170. }
  171. /*
  172. * The next two functions depend on IEEE-format floating point numbers.
  173. * They are (thus?) potentially a portability trap, but may suffice for
  174. * MOST systems. I need to test the handling of double precision values
  175. * on computers that store the two words of a double in each of the
  176. * possible orders. If the exponent field in floats was not stored in the
  177. * position that would be 0x7f800000 in an integer my treatment of short
  178. * floats would fail, so I have already assumed that that is so. I think.
  179. */
  180. static Lisp_Object Lfloat_denormalized_p(Lisp_Object nil, Lisp_Object a)
  181. {
  182. int x = 0;
  183. switch ((int)a & TAG_BITS)
  184. {
  185. #ifdef COMMON
  186. case TAG_SFLOAT:
  187. if ((a & 0x7fffffff) == TAG_SFLOAT) return onevalue(nil); /* 0.0 */
  188. x = (int32)a & 0x7f800000;
  189. return onevalue(x == 0 ? lisp_true : nil);
  190. #endif
  191. case TAG_BOXFLOAT:
  192. switch (type_of_header(flthdr(a)))
  193. {
  194. #ifdef COMMON
  195. case TYPE_SINGLE_FLOAT:
  196. if (single_float_val(a) == 0.0) return onevalue(nil);
  197. x = ((Single_Float *)((char *)a-TAG_BOXFLOAT))->f.i & 0x7f800000;
  198. return onevalue(x == 0 ? lisp_true : nil);
  199. case TYPE_LONG_FLOAT:
  200. if (long_float_val(a) == 0.0) return onevalue(nil);
  201. x = ((Long_Float *)((char *)a-TAG_BOXFLOAT)
  202. )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
  203. return onevalue(x == 0 ? lisp_true : nil);
  204. #endif
  205. case TYPE_DOUBLE_FLOAT:
  206. if (double_float_val(a) == 0.0) return onevalue(nil);
  207. x = ((Double_Float *)((char *)a-TAG_BOXFLOAT)
  208. )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
  209. return onevalue(x == 0 ? lisp_true : nil);
  210. }
  211. default:
  212. break;
  213. }
  214. return onevalue(nil);
  215. }
  216. static Lisp_Object Lfloat_infinity_p(Lisp_Object nil, Lisp_Object a)
  217. {
  218. /*
  219. * The issue of NaN values is one I do not want to worry about at present.
  220. * I deem anything with the largest possibl exponent value to be infinite.
  221. */
  222. int x = 0;
  223. switch ((int)a & TAG_BITS)
  224. {
  225. #ifdef COMMON
  226. case TAG_SFLOAT:
  227. x = (int32)a & 0x7f800000;
  228. return onevalue(x == 0x7f800000 ? lisp_true : nil);
  229. #endif
  230. case TAG_BOXFLOAT:
  231. switch (type_of_header(flthdr(a)))
  232. {
  233. #ifdef COMMON
  234. case TYPE_SINGLE_FLOAT:
  235. if (single_float_val(a) == 0.0) return onevalue(nil);
  236. x = ((Single_Float *)((char *)a-TAG_BOXFLOAT))->f.i & 0x7f800000;
  237. return onevalue(x == 0x7f800000 ? lisp_true : nil);
  238. case TYPE_LONG_FLOAT:
  239. if (long_float_val(a) == 0.0) return onevalue(nil);
  240. x = ((Long_Float *)((char *)a-TAG_BOXFLOAT)
  241. )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
  242. return onevalue(x == 0x7ff00000 ? lisp_true : nil);
  243. #endif
  244. case TYPE_DOUBLE_FLOAT:
  245. if (double_float_val(a) == 0.0) return onevalue(nil);
  246. x = ((Double_Float *)((char *)a-TAG_BOXFLOAT)
  247. )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
  248. return onevalue(x == 0x7ff00000 ? lisp_true : nil);
  249. }
  250. default:
  251. break;
  252. }
  253. return onevalue(nil);
  254. }
  255. static Lisp_Object Ldenominator(Lisp_Object nil, Lisp_Object a)
  256. {
  257. CSL_IGNORE(nil);
  258. if (!is_number(a)) return aerror1("denominator", a);
  259. if (is_numbers(a) && is_ratio(a))
  260. return onevalue(denominator(a));
  261. else return onevalue(fixnum_of_int(1));
  262. }
  263. static Lisp_Object MS_CDECL Ldeposit_field(Lisp_Object nil, int nargs, ...)
  264. {
  265. va_list aa;
  266. Lisp_Object a, b, c;
  267. CSL_IGNORE(nil);
  268. CSL_IGNORE(nargs);
  269. va_start(aa, nargs);
  270. a = va_arg(aa, Lisp_Object);
  271. b = va_arg(aa, Lisp_Object);
  272. c = va_arg(aa, Lisp_Object);
  273. va_end(aa);
  274. return aerror("deposit-field");
  275. }
  276. static Lisp_Object MS_CDECL Ldpb(Lisp_Object nil, int nargs, ...)
  277. {
  278. va_list aa;
  279. Lisp_Object a, b, c;
  280. CSL_IGNORE(nil);
  281. CSL_IGNORE(nargs);
  282. va_start(aa, nargs);
  283. a = va_arg(aa, Lisp_Object);
  284. b = va_arg(aa, Lisp_Object);
  285. c = va_arg(aa, Lisp_Object);
  286. va_end(aa);
  287. return aerror("dpb");
  288. }
  289. static Lisp_Object Lffloor(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  290. {
  291. CSL_IGNORE(nil);
  292. CSL_IGNORE(a);
  293. CSL_IGNORE(b);
  294. return aerror("ffloor");
  295. }
  296. /*
  297. * The functions such as float-digits, float-precision, float-radix are
  298. * coded here assuming that IEEE-style arithmetic is being used. If this is
  299. * not so then all the code in this file needs review. Furthermore I will
  300. * be lazy about NaNs and denormalised numbers for now and come back to
  301. * worry about them later on if I am really forced to.
  302. */
  303. static Lisp_Object Lfloat_digits(Lisp_Object nil, Lisp_Object a)
  304. {
  305. int tag = (int)a & TAG_BITS;
  306. CSL_IGNORE(nil);
  307. switch (tag)
  308. {
  309. #ifdef COMMON
  310. case TAG_SFLOAT:
  311. return onevalue(fixnum_of_int(20));
  312. #endif
  313. case TAG_BOXFLOAT:
  314. switch (type_of_header(flthdr(a)))
  315. {
  316. #ifdef COMMON
  317. case TYPE_SINGLE_FLOAT:
  318. return onevalue(fixnum_of_int(24));
  319. #endif
  320. default:
  321. return onevalue(fixnum_of_int(53));
  322. }
  323. default:
  324. return aerror("float-digits");
  325. }
  326. }
  327. static Lisp_Object Lfloat_precision(Lisp_Object nil, Lisp_Object a)
  328. {
  329. int tag = (int)a & TAG_BITS;
  330. double d = float_of_number(a);
  331. CSL_IGNORE(nil);
  332. if (d == 0.0) return onevalue(fixnum_of_int(0));
  333. /* /* I do not cope with de-normalised numbers here */
  334. switch (tag)
  335. {
  336. #ifdef COMMON
  337. case TAG_SFLOAT:
  338. return onevalue(fixnum_of_int(20));
  339. #endif
  340. case TAG_BOXFLOAT:
  341. switch (type_of_header(flthdr(a)))
  342. {
  343. #ifdef COMMON
  344. case TYPE_SINGLE_FLOAT:
  345. return onevalue(fixnum_of_int(24));
  346. #endif
  347. default:
  348. return onevalue(fixnum_of_int(53));
  349. }
  350. default:
  351. return aerror("float-precision");
  352. }
  353. }
  354. static Lisp_Object Lfloat_radix(Lisp_Object nil, Lisp_Object a)
  355. {
  356. CSL_IGNORE(nil);
  357. CSL_IGNORE(a);
  358. return onevalue(fixnum_of_int(FLT_RADIX));
  359. }
  360. static Lisp_Object Lfloat_sign2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  361. {
  362. double d = float_of_number(b);
  363. CSL_IGNORE(nil);
  364. if (float_of_number(a) < 0.0) d = -d;
  365. if (is_sfloat(b)) return onevalue(make_sfloat(d));
  366. else if (!is_bfloat(b)) return aerror1("bad arg for float-sign", b);
  367. else return onevalue(make_boxfloat(d, type_of_header(flthdr(b))));
  368. }
  369. static Lisp_Object Lfloat_sign1(Lisp_Object nil, Lisp_Object a)
  370. {
  371. double d = float_of_number(a);
  372. CSL_IGNORE(nil);
  373. if (d < 0.0) d = -1.0; else d = 1.0;
  374. if (is_sfloat(a)) return onevalue(make_sfloat(d));
  375. else if (!is_bfloat(a)) return aerror1("bad arg for float-sign", a);
  376. else return onevalue(make_boxfloat(d, type_of_header(flthdr(a))));
  377. }
  378. static Lisp_Object Lfround(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  379. {
  380. CSL_IGNORE(nil);
  381. CSL_IGNORE(a);
  382. CSL_IGNORE(b);
  383. return aerror("fround");
  384. }
  385. static Lisp_Object Lftruncate(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  386. {
  387. CSL_IGNORE(nil);
  388. CSL_IGNORE(a);
  389. CSL_IGNORE(b);
  390. return aerror("ftruncate");
  391. }
  392. Lisp_Object MS_CDECL Lgcd_n(Lisp_Object nil, int nargs, ...)
  393. {
  394. va_list a;
  395. int i;
  396. Lisp_Object r;
  397. if (nargs == 0) return fixnum_of_int(0);
  398. va_start(a, nargs);
  399. push_args(a, nargs);
  400. /*
  401. * The actual args have been passed a C args - I can not afford to
  402. * risk garbage collection until they have all been moved somewhere safe,
  403. * and here that safe place is the Lisp stack. I have to delay checking for
  404. * overflow on same until all args have been pushed.
  405. */
  406. stackcheck0(nargs);
  407. pop(r);
  408. for (i = 1; i<nargs; i++)
  409. { Lisp_Object w;
  410. if (r == fixnum_of_int(1))
  411. { popv(nargs-i);
  412. break;
  413. }
  414. pop(w);
  415. r = gcd(r, w);
  416. errexitn(nargs-i-1);
  417. }
  418. return onevalue(r);
  419. }
  420. Lisp_Object Lgcd(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  421. {
  422. a = gcd(a, b);
  423. errexit();
  424. return onevalue(a);
  425. }
  426. Lisp_Object Lgcd_1(Lisp_Object nil, Lisp_Object a)
  427. {
  428. CSL_IGNORE(nil);
  429. return onevalue(a);
  430. }
  431. static Lisp_Object Limagpart(Lisp_Object nil, Lisp_Object a)
  432. {
  433. CSL_IGNORE(nil);
  434. if (!is_number(a)) return aerror1("imagpart", a);
  435. if (is_numbers(a) && is_complex(a))
  436. return onevalue(imag_part(a));
  437. /* /* the 0.0 returned here ought to be the same type as a has */
  438. else return onevalue(fixnum_of_int(0));
  439. }
  440. static Lisp_Object Linteger_decode_float(Lisp_Object nil, Lisp_Object a)
  441. {
  442. double d = float_of_number(a);
  443. int tag = (int)a & TAG_BITS, x, neg = 0;
  444. int32 a1, a2;
  445. CSL_IGNORE(nil);
  446. if (!is_float(a)) return aerror("integer-decode-float");
  447. if (d == 0.0)
  448. #ifdef COMMON
  449. { mv_2 = fixnum_of_int(0);
  450. mv_3 = fixnum_of_int(1);
  451. nvalues(a, 3);
  452. }
  453. #else
  454. return list3(a, fixnum_of_int(0), fixnum_of_int(1));
  455. #endif
  456. if (d < 0.0) d = -d, neg = 1;
  457. d = frexp(d, &x);
  458. if (d == 1.0) d = 0.5, x++;
  459. #ifdef COMMON
  460. if (tag == TAG_SFLOAT)
  461. { d *= TWO_20;
  462. x -= 20;
  463. a1 = (int32)d;
  464. a = fixnum_of_int(a1);
  465. }
  466. else if (tag == TAG_BOXFLOAT &&
  467. type_of_header(flthdr(a)) == TYPE_SINGLE_FLOAT)
  468. { d *= TWO_24;
  469. x -= 24;
  470. a1 = (int32)d;
  471. a = fixnum_of_int(a1);
  472. }
  473. else
  474. #endif
  475. { d *= TWO_22;
  476. a1 = (int32)d;
  477. d -= (double)a1;
  478. a2 = (int32)(d*TWO_31); /* This conversion should be exact */
  479. x -= 53;
  480. a = make_two_word_bignum(a1, a2);
  481. errexit();
  482. }
  483. #ifdef COMMON
  484. { mv_2 = fixnum_of_int(x);
  485. mv_3 = neg ? fixnum_of_int(-1) : fixnum_of_int(1);
  486. return nvalues(a, 3);
  487. }
  488. #else
  489. return list3(a, fixnum_of_int(x),
  490. neg ? fixnum_of_int(-1) : fixnum_of_int(1));
  491. #endif
  492. }
  493. static Lisp_Object Linteger_length(Lisp_Object nil, Lisp_Object a)
  494. {
  495. a = Labsval(nil, a);
  496. errexit();
  497. return Lmsd(nil, a);
  498. }
  499. static Lisp_Object Lldb(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  500. {
  501. CSL_IGNORE(nil);
  502. CSL_IGNORE(a);
  503. CSL_IGNORE(b);
  504. return aerror("ldb");
  505. }
  506. Lisp_Object MS_CDECL Llcm_n(Lisp_Object nil, int nargs, ...)
  507. {
  508. va_list a;
  509. int i;
  510. Lisp_Object r;
  511. if (nargs == 0) return onevalue(fixnum_of_int(1));
  512. va_start(a, nargs);
  513. push_args(a, nargs);
  514. stackcheck0(nargs);
  515. pop(r);
  516. for (i = 1; i<nargs; i++)
  517. { Lisp_Object w;
  518. pop(w);
  519. r = lcm(r, w);
  520. errexitn(nargs-i-1);
  521. }
  522. return onevalue(r);
  523. }
  524. Lisp_Object Llcm(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  525. {
  526. a = lcm(a, b);
  527. errexit();
  528. return onevalue(a);
  529. }
  530. Lisp_Object Llcm_1(Lisp_Object nil, Lisp_Object a)
  531. {
  532. CSL_IGNORE(nil);
  533. return onevalue(a);
  534. }
  535. static Lisp_Object Lldb_test(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  536. {
  537. CSL_IGNORE(nil);
  538. CSL_IGNORE(a);
  539. CSL_IGNORE(b);
  540. return aerror("ldb-test");
  541. }
  542. static Lisp_Object Llogbitp(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  543. {
  544. CSL_IGNORE(nil);
  545. CSL_IGNORE(a);
  546. CSL_IGNORE(b);
  547. return aerror("logbitp");
  548. }
  549. static Lisp_Object Llogcount(Lisp_Object nil, Lisp_Object a)
  550. {
  551. CSL_IGNORE(nil);
  552. CSL_IGNORE(a);
  553. return aerror("logcount");
  554. }
  555. static Lisp_Object Llogtest(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  556. {
  557. CSL_IGNORE(nil);
  558. CSL_IGNORE(a);
  559. CSL_IGNORE(b);
  560. return aerror("logtest");
  561. }
  562. static Lisp_Object Lmask_field(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  563. {
  564. CSL_IGNORE(nil);
  565. CSL_IGNORE(a);
  566. CSL_IGNORE(b);
  567. return aerror("mask-field");
  568. }
  569. static Lisp_Object Lnumerator(Lisp_Object nil, Lisp_Object a)
  570. {
  571. CSL_IGNORE(nil);
  572. if (!is_number(a)) return aerror1("numerator", a);
  573. if (is_numbers(a) && is_ratio(a))
  574. return onevalue(numerator(a));
  575. else return onevalue(a);
  576. }
  577. static Lisp_Object Lrealpart(Lisp_Object nil, Lisp_Object a)
  578. {
  579. CSL_IGNORE(nil);
  580. if (!is_number(a)) return aerror1("realpart", a);
  581. if (is_numbers(a) && is_complex(a))
  582. return onevalue(real_part(a));
  583. else return onevalue(a);
  584. }
  585. static Lisp_Object Lscale_float(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  586. {
  587. double d = float_of_number(a);
  588. CSL_IGNORE(nil);
  589. if (!is_fixnum(b)) return aerror("scale-float");
  590. d = ldexp(d, int_of_fixnum(b));
  591. if (is_sfloat(a)) return onevalue(make_sfloat(d));
  592. else if (!is_bfloat(a)) return aerror1("bad arg for scale-float", a);
  593. else return onevalue(make_boxfloat(d, type_of_header(flthdr(a))));
  594. }
  595. #else /* COMMON */
  596. Lisp_Object Lgcd(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  597. {
  598. a = gcd(a, b);
  599. errexit();
  600. return onevalue(a);
  601. }
  602. Lisp_Object Llcm(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  603. {
  604. Lisp_Object g;
  605. push2(b, a);
  606. g = gcd(a, b);
  607. errexitn(2);
  608. pop(a);
  609. a = quot2(a, g);
  610. pop(b);
  611. errexit();
  612. a = times2(a, b);
  613. errexit();
  614. return onevalue(a);
  615. }
  616. #endif /* COMMON */
  617. #define FIX_TRUNCATE 0
  618. #define FIX_ROUND 1
  619. #define FIX_FLOOR 2
  620. #define FIX_CEILING 3
  621. static Lisp_Object lisp_fix_sub(Lisp_Object a, int roundmode)
  622. /*
  623. * This converts from a double to a Lisp integer, which will
  624. * quite often have to be a bignum. No overflow is permitted - the
  625. * result can always be accurate.
  626. */
  627. {
  628. int32 a0, a1, a2, a3;
  629. int x, x1;
  630. CSLbool negative;
  631. double d = float_of_number(a);
  632. if (M2_31_1 < d && d < TWO_31)
  633. { int32 a = (int32)d;
  634. /*
  635. * If my floating point value is in the range -(2^31+1) to +2^31 (exclusive)
  636. * then when C truncates it I will get an integer in the inclusive range
  637. * from -2^31 to 2^31-1, i.e. the whole range of C 32-bit integers.
  638. * If I then apply a rounding mode other than truncation I may just have
  639. * overflow, which I have to detect specially.
  640. */
  641. int32 w;
  642. double f;
  643. switch (roundmode)
  644. {
  645. case FIX_TRUNCATE:
  646. break; /* C casts truncate, so this is OK */
  647. case FIX_ROUND:
  648. f = d - (double)a;
  649. if (f > 0.5)
  650. { if (a == 0x7fffffff) return make_two_word_bignum(1, 0);
  651. else a++;
  652. }
  653. else if (f < -0.5)
  654. { if (a == ~0x7fffffff)
  655. return make_two_word_bignum(-2, 0x7fffffff);
  656. else a--;
  657. }
  658. /* The rounding rule on the next lines show what I do in 1/2ulp cases */
  659. else if (f == 0.5) a = (a+1) & ~1;
  660. else if (f == -0.5)
  661. { if (a == ~0x7fffffff)
  662. return make_two_word_bignum(-2, 0x7fffffff);
  663. else a = a & ~1;
  664. }
  665. break;
  666. case FIX_FLOOR:
  667. f = d - (double)a;
  668. if (f < 0.0)
  669. { if (a == ~0x7fffffff)
  670. return make_two_word_bignum(-2, 0x7fffffff);
  671. else a--;
  672. }
  673. break;
  674. case FIX_CEILING:
  675. f = d - (double)a;
  676. if (f > 0.0)
  677. { if (a == 0x7fffffff) return make_two_word_bignum(1, 0);
  678. else a++;
  679. }
  680. break;
  681. }
  682. w = a & fix_mask;
  683. if (w == 0 || w == fix_mask) return fixnum_of_int(a);
  684. else if (!signed_overflow(a)) return make_one_word_bignum(a);
  685. else if (a > 0) return make_two_word_bignum(0, a);
  686. else return make_two_word_bignum(-1, clear_top_bit(a));
  687. }
  688. if (d < 0.0) d = -d, negative = YES;
  689. else negative = NO;
  690. d = frexp(d, &x); /* 0.5 <= abs(d) < 1.0, x = the (binary) exponent */
  691. if (d == 1.0) d = 0.5, x++;
  692. d *= TWO_31;
  693. a1 = (int32)d; /* 2^31 > d >= 2^30 */
  694. d -= (double)a1;
  695. a2 = (unsigned32)(d*TWO_31); /* This conversion should be exact */
  696. if (negative)
  697. { if (a2 == 0) a1 = -a1;
  698. else a2 = clear_top_bit(-a2), a1 = ~a1;
  699. }
  700. x -= 62;
  701. if (x < 0) /* Need to shift right x places */
  702. { x = -x; /* The shift amount here can be 31 at most... */
  703. a3 = a2 << (32 - x);
  704. a2 = clear_top_bit((a2 >> x) | (a1 << (31 - x)));
  705. #ifdef SIGNED_SHIFTS_ARE_LOGICAL
  706. if (a1 < 0) a1 = (a1 >> x) | (((int32)-1) << (31 - x));
  707. else a1 = a1 >> x;
  708. #else
  709. a1 = a1 >> x;
  710. #endif
  711. switch (roundmode)
  712. {
  713. case FIX_TRUNCATE:
  714. if (a1 < 0 && a3 != 0) /* proper rounding on -ve values */
  715. { a2++;
  716. if (a2 < 0) /* carry */
  717. { a2 = 0;
  718. a1++;
  719. }
  720. }
  721. break;
  722. case FIX_ROUND:
  723. if ((a3 & 0x80000000U) != 0 &&
  724. (a3 != ~0x7fffffff || (a2 & 1) != 0))
  725. { a2++;
  726. if (a2 < 0) /* carry */
  727. { a2 = 0;
  728. a1++;
  729. }
  730. }
  731. break;
  732. case FIX_FLOOR: /* Comes out in wash of 2's complement */
  733. break;
  734. case FIX_CEILING:
  735. if (a3 != 0)
  736. { a2++;
  737. if (a2 < 0) /* carry */
  738. { a2 = 0;
  739. a1++;
  740. }
  741. }
  742. break;
  743. }
  744. return make_two_word_bignum(a1, a2);
  745. }
  746. /* Now the double-length value (a1,a2) is correct and exact, and it
  747. * needs shifting left by x bits. This will give a 3 or more word bignum.
  748. * Note that no rounding etc is needed at all here since there are no
  749. * fractional bits in the representation.
  750. */
  751. if (a1 < 0)
  752. { a0 = -1;
  753. a1 = clear_top_bit(a1);
  754. }
  755. else a0 = 0;
  756. x1 = x / 31;
  757. x = x % 31;
  758. a0 = (a0 << x) | (a1 >> (31-x));
  759. a1 = clear_top_bit(a1 << x) | (a2 >> (31-x));
  760. a2 = clear_top_bit(a2 << x);
  761. return make_n_word_bignum(a0, a1, a2, x1);
  762. }
  763. #ifdef COMMON
  764. static Lisp_Object lisp_fix_ratio(Lisp_Object a, int roundmode)
  765. /*
  766. * This converts from a ratio to a Lisp integer. It has to apply
  767. * the specified rounding regime.
  768. */
  769. {
  770. Lisp_Object p, q, r, nil = C_nil;;
  771. p = numerator(a);
  772. q = denominator(a);
  773. push2(q, p);
  774. r = quot2(p, q);
  775. errexitn(2);
  776. p = stack[0];
  777. stack[0] = r;
  778. p = Cremainder(p, stack[-1]);
  779. pop2(r, q);
  780. errexit();
  781. switch (roundmode)
  782. {
  783. case FIX_TRUNCATE:
  784. break;
  785. case FIX_ROUND:
  786. /* /* This case unfinished at present */
  787. break;
  788. case FIX_FLOOR:
  789. if (minusp(p))
  790. { push(r);
  791. p = plus2(p, q);
  792. pop(r);
  793. errexit();
  794. r = sub1(r);
  795. errexit();
  796. }
  797. break;
  798. case FIX_CEILING:
  799. if (plusp(p))
  800. { push(r);
  801. p = difference2(p, q);
  802. pop(r);
  803. errexit();
  804. r = add1(r);
  805. errexit();
  806. }
  807. break;
  808. }
  809. mv_2 = p;
  810. return nvalues(r, 2);
  811. }
  812. #endif
  813. static Lisp_Object lisp_fix(Lisp_Object a, int roundmode)
  814. {
  815. Lisp_Object r, nil;
  816. push(a);
  817. r = lisp_fix_sub(a, roundmode);
  818. errexitn(1);
  819. a = stack[0];
  820. stack[0] = r;
  821. a = difference2(a, r);
  822. pop(r);
  823. errexit();
  824. mv_2 = a;
  825. return nvalues(r, 2);
  826. }
  827. static Lisp_Object lisp_ifix(Lisp_Object a, Lisp_Object b, int roundmode)
  828. {
  829. Lisp_Object q, r, nil;
  830. if (is_float(a) || is_float(b))
  831. { double p = float_of_number(a), q = float_of_number(b), d = p/q;
  832. a = make_boxfloat(d, TYPE_DOUBLE_FLOAT);
  833. errexit();
  834. r = lisp_fix(a, roundmode);
  835. errexit();
  836. push(r);
  837. a = make_boxfloat(float_of_number(mv_2)*q, TYPE_DOUBLE_FLOAT);
  838. pop(r);
  839. errexit();
  840. mv_2 = a;
  841. return nvalues(r, 2);
  842. }
  843. push2(a, b);
  844. q = quot2(a, b);
  845. errexitn(2);
  846. a = stack[-1];
  847. b = stack[0];
  848. push(q);
  849. r = Cremainder(a, b);
  850. errexitn(3);
  851. switch (roundmode)
  852. {
  853. case FIX_TRUNCATE:
  854. break;
  855. case FIX_ROUND:
  856. popv(3); return aerror("two-arg ROUND");
  857. case FIX_FLOOR:
  858. if (!minusp(r)) break;
  859. r = plus2(r, stack[-1]);
  860. errexitn(3);
  861. q = stack[0];
  862. push(r);
  863. q = sub1(q);
  864. pop(r);
  865. errexitn(3);
  866. stack[0] = q;
  867. break;
  868. case FIX_CEILING:
  869. if (!plusp(r)) break;
  870. r = difference2(r, stack[-1]);
  871. errexitn(3);
  872. q = stack[0];
  873. push(r);
  874. q = add1(q);
  875. pop(r);
  876. errexitn(3);
  877. stack[0] = q;
  878. break;
  879. }
  880. pop3(q, b, a);
  881. mv_2 = r;
  882. return nvalues(q, 2);
  883. }
  884. /*
  885. * So far I have not implemented support for rational numbers in the 2-arg
  886. * versions of these functions. /*
  887. */
  888. static Lisp_Object Lceiling_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  889. {
  890. CSL_IGNORE(nil);
  891. if (!is_number(a) || !is_number(b)) return aerror1("ceiling", a);
  892. return lisp_ifix(a, b, FIX_CEILING);
  893. }
  894. static Lisp_Object Lfloor_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  895. {
  896. CSL_IGNORE(nil);
  897. if (!is_number(a) || !is_number(b)) return aerror1("floor", a);
  898. return lisp_ifix(a, b, FIX_FLOOR);
  899. }
  900. static Lisp_Object Lround_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  901. {
  902. CSL_IGNORE(nil);
  903. if (!is_number(a) || !is_number(b)) return aerror1("round", a);
  904. return lisp_ifix(a, b, FIX_ROUND);
  905. }
  906. Lisp_Object Ltruncate_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  907. {
  908. CSL_IGNORE(nil);
  909. if (!is_number(a) || !is_number(b)) return aerror1("truncate", a);
  910. return lisp_ifix(a, b, FIX_TRUNCATE);
  911. }
  912. static Lisp_Object Lceiling(Lisp_Object nil, Lisp_Object a)
  913. {
  914. CSL_IGNORE(nil);
  915. if (!is_number(a)) return aerror1("ceiling", a);
  916. #ifdef COMMON
  917. if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_CEILING);
  918. #endif
  919. if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
  920. return lisp_fix(a, FIX_CEILING);
  921. }
  922. static Lisp_Object Lfloor(Lisp_Object nil, Lisp_Object a)
  923. {
  924. CSL_IGNORE(nil);
  925. if (!is_number(a)) return aerror1("floor", a);
  926. #ifdef COMMON
  927. if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_FLOOR);
  928. #endif
  929. if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
  930. return lisp_fix(a, FIX_FLOOR);
  931. }
  932. static Lisp_Object Lround(Lisp_Object nil, Lisp_Object a)
  933. {
  934. CSL_IGNORE(nil);
  935. if (!is_number(a)) return aerror1("round", a);
  936. #ifdef COMMON
  937. if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_ROUND);
  938. #endif
  939. if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
  940. return lisp_fix(a, FIX_ROUND);
  941. }
  942. Lisp_Object Ltruncate(Lisp_Object nil, Lisp_Object a)
  943. {
  944. CSL_IGNORE(nil);
  945. if (!is_number(a)) return aerror1("fix", a);
  946. #ifdef COMMON
  947. if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_TRUNCATE);
  948. #endif
  949. if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
  950. return lisp_fix(a, FIX_TRUNCATE);
  951. }
  952. /*
  953. * The following macro is expected to select out the 32-bit word within a
  954. * floating point number that has the exponent field packed within it.
  955. * On IEEE-format machines I expect to find the exponent in the
  956. * 0x7ff00000 bits within this word.
  957. */
  958. #define top_half(d) ((int32 *)&(d))[(~current_fp_rep) & FP_WORD_ORDER]
  959. /*
  960. * symbolic procedure safe!-fp!-plus(x,y);
  961. * if zerop x then y else if zerop y then x else
  962. * begin scalar u;
  963. * if x>0.0 and y>0.0 then
  964. * if x<!!plumax and y<!!plumax then go to ret else return nil;
  965. * if x<0.0 and y<0.0 then
  966. * if -x<!!plumax and -y<!!plumax then go to ret else return nil;
  967. * if abs x<!!plumin and abs y<!!plumin then return nil;
  968. * ret: return
  969. * if (u := plus2(x,y))=0.0
  970. * or x>0.0 and y>0.0 or x<0.0 and y<0.0 then u
  971. * else if abs u<(abs x)*!!fleps1 then 0.0 else u end;
  972. */
  973. static Lisp_Object Lsafe_fp_plus(Lisp_Object env, Lisp_Object a, Lisp_Object b)
  974. /*
  975. * safe!-fp!-plus must always be given floating point arguments. In
  976. * most reasonable cases it just returns the floating point sum. If
  977. * there was some chance that the sum might either overflow or underflow
  978. * then the value NIL is returned instead. The exact place where this
  979. * function starts to report overflow is not precisely defined - all that
  980. * is guaranteed is that if a result is returned then it will be of full
  981. * precision.
  982. */
  983. {
  984. Lisp_Object nil = C_nil;
  985. double aa, bb, cc;
  986. int32 ah, bh;
  987. if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-plus", a, b);
  988. /*
  989. * I accept here that adding 0.0 to anything is always possible without
  990. * problem.
  991. */
  992. if ((aa = double_float_val(a)) == 0.0) return onevalue(b);
  993. if ((bb = double_float_val(b)) == 0.0) return onevalue(a);
  994. if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
  995. return aerror("VAX or 370 FP rep");
  996. ah = top_half(aa);
  997. bh = top_half(bb);
  998. /*
  999. * Here I am going to assume IEEE-format numbers. I hope that I have
  1000. * picked out the word containing the exponent and that it is positioned in
  1001. * the word where I expect.
  1002. */
  1003. /*
  1004. * I deem overflow POSSIBLE if both numbers have the same sign and if at
  1005. * least one of them has an exponent 0x7fe (i.e. the highest exponent that
  1006. * a non-infinite number can have).
  1007. */
  1008. if (ah >= 0)
  1009. { if (bh >= 0)
  1010. { if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
  1011. cc = aa + bb;
  1012. }
  1013. else
  1014. /*
  1015. * I deem underflow POSSIBLE if the numbers have opposite signs and BOTH
  1016. * of them have exponents less than 0x035 (which is 53 in decimal, and
  1017. * IEEE-format numbers have 53-bit mantissas. The critical case would
  1018. * be the subtraction
  1019. * (53) 1 00000000000000000000 00000000000000000000000000000001
  1020. * - (53) 1 00000000000000000000 00000000000000000000000000000000
  1021. * where you see the LSB (which is all that is left after the subtraction)
  1022. * has to be shifted left 52 bits to get to the position of the implied
  1023. * leading 1 bit in the mantissa. As that happens 52 gets subtracted
  1024. * from the exponent, leaving it as 1, the smallest exponent for a normalised
  1025. * non-zero value.
  1026. */
  1027. { double eps, ra;
  1028. bh &= 0x7fffffff;
  1029. if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
  1030. /*
  1031. * The next few lines check to see if addition has led to cancellation of
  1032. * leading digits to an extent greater than !!fleps1. The environent cell
  1033. * of safe!-fp!-plus must be set to !!fleps, and then the value cell of
  1034. * this symbol is accessed to obtain the limit.
  1035. */
  1036. eps = 0.0;
  1037. if (is_symbol(env))
  1038. { Lisp_Object ve = qvalue(env);
  1039. if (is_float(ve)) eps = double_float_val(ve);
  1040. }
  1041. cc = aa + bb;
  1042. ra = cc/aa;
  1043. if (ra < 0.0) ra = -ra;
  1044. if (ra < eps) cc = 0.0; /* Force to zero if too small */
  1045. }
  1046. }
  1047. else
  1048. { if (bh >= 0)
  1049. { double eps, ra;
  1050. ah &= 0x7fffffff;
  1051. if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
  1052. eps = 0.0;
  1053. if (is_symbol(env))
  1054. { Lisp_Object ve = qvalue(env);
  1055. if (is_float(ve)) eps = double_float_val(ve);
  1056. }
  1057. cc = aa + bb;
  1058. ra = cc/aa;
  1059. if (ra < 0.0) ra = -ra;
  1060. if (ra < eps) cc = 0.0;
  1061. }
  1062. else
  1063. { ah &= 0x7fffffff;
  1064. bh &= 0x7fffffff;
  1065. if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
  1066. cc = aa + bb;
  1067. }
  1068. }
  1069. a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
  1070. errexit();
  1071. return onevalue(a);
  1072. }
  1073. /*
  1074. * symbolic procedure safe!-fp!-times(x,y);
  1075. * if zerop x or zerop y then 0.0
  1076. * else if x=1.0 then y else if y=1.0 then x else
  1077. * begin scalar u,v; u := abs x; v := abs y;
  1078. * if u>=1.0 and u<=!!timmax then
  1079. * if v<=!!timmax then go to ret else return nil;
  1080. * if u>!!timmax then if v<=1.0 then go to ret else return nil;
  1081. * if u<1.0 and u>=!!timmin then
  1082. * if v>=!!timmin then go to ret else return nil;
  1083. * if u<!!timmin and v<1.0 then return nil;
  1084. * ret: return times2(x,y) end;
  1085. */
  1086. static Lisp_Object Lsafe_fp_times(Lisp_Object nil,
  1087. Lisp_Object a, Lisp_Object b)
  1088. /*
  1089. * safe!-fp!-times must always be given floating point arguments. In
  1090. * most reasonable cases it just returns the floating point product. If
  1091. * there was some chance that the product might either overflow or underflow
  1092. * then the value NIL is returned instead. REDUCE requires that if this
  1093. * function returns a non-overflow result than two such returned values
  1094. * can be added witjout fear of overflow, as in a*b+c*d. Hence I ought to
  1095. * report trouble slightly earlier than I might otherwise. - but REDUCE is
  1096. * being changed to remove this oddity, and it seems it could only cause
  1097. * trouble in (1.0,max)*(max, 1.0) complex multiplication, so I am not
  1098. * going to worry...
  1099. */
  1100. {
  1101. double aa, bb, cc;
  1102. int32 ah, bh;
  1103. if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-times", a, b);
  1104. /*
  1105. * Multiplication by zero is handled as a special case here - doing so
  1106. * means that I do not have to worry about the special case of zero
  1107. * exponents later on, and it also avoids allocating fresh space to hold
  1108. * a new floating point zero value.
  1109. */
  1110. if ((aa = double_float_val(a)) == 0.0) return onevalue(a);
  1111. if ((bb = double_float_val(b)) == 0.0) return onevalue(b);
  1112. if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
  1113. return aerror("VAX or 370 FP rep");
  1114. ah = top_half(aa);
  1115. bh = top_half(bb);
  1116. /*
  1117. * Here I am going to assume IEEE-format numbers. I hope that I have
  1118. * picked out the word containing the exponent and that it is positioned in
  1119. * the word where I expect.
  1120. */
  1121. ah = (ah >> 20) & 0x7ff;
  1122. bh = (bh >> 20) & 0x7ff;
  1123. ah = ah + bh;
  1124. /*
  1125. * I can estimate the value of the product by adding the exponents of the
  1126. * two operands.
  1127. */
  1128. if (ah < 0x400 || ah >= 0xbfd) return onevalue(nil);
  1129. cc = aa * bb;
  1130. a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
  1131. errexit();
  1132. return onevalue(a);
  1133. }
  1134. /*
  1135. * symbolic procedure safe!-fp!-quot(x,y);
  1136. * if zerop y then rdqoterr()
  1137. * else if zerop x then 0.0 else if y=1.0 then x else
  1138. * begin scalar u,v; u := abs x; v := abs y;
  1139. * if u>=1.0 and u<=!!timmax then
  1140. * if v>=!!timmin then go to ret else return nil;
  1141. * if u>!!timmax then if v>=1.0 then go to ret else return nil;
  1142. * if u<1.0 and u>=!!timmin then
  1143. * if v<=!!timmax then go to ret else return nil;
  1144. * if u<!!timmin and v>1.0 then return nil;
  1145. * ret: return quotient(x,y) end;
  1146. */
  1147. static Lisp_Object Lsafe_fp_quot(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  1148. {
  1149. double aa, bb, cc;
  1150. int32 ah, bh;
  1151. if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-quot", a, b);
  1152. if ((aa = double_float_val(a)) == 0.0) return onevalue(a);
  1153. /*
  1154. * I pass division by zero back to the general case here.
  1155. */
  1156. if ((bb = double_float_val(b)) == 0.0) return onevalue(nil);
  1157. if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
  1158. return aerror("VAX or 370 FP rep");
  1159. ah = top_half(aa);
  1160. bh = top_half(bb);
  1161. ah = (ah >> 20) & 0x7ff;
  1162. bh = (bh >> 20) & 0x7ff;
  1163. ah = ah - bh;
  1164. if (ah <= -0x3fe || ah >= 0x3fe) return onevalue(nil);
  1165. cc = aa / bb;
  1166. a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
  1167. errexit();
  1168. return onevalue(a);
  1169. }
  1170. /*
  1171. * symbolic procedure safe!-fp!-pl(x,y);
  1172. * % floating plus protect from under- and over-flows but no zero
  1173. * % result check.
  1174. * if zerop x then y else if zerop y then x
  1175. * else if x>0 and y>0 then
  1176. * if x<!!plumax and y<!!plumax then plus2(x,y) else nil
  1177. * else if x<0 and y<0 then
  1178. * if (-x<!!plumax and -y<!!plumax) then plus2(x,y) else nil
  1179. * else if abs x<!!plumin or abs y<!!plumin then nil else plus2(x,y);
  1180. */
  1181. static Lisp_Object Lsafe_fp_pl(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  1182. {
  1183. double aa, bb, cc;
  1184. int32 ah, bh;
  1185. if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-pl", a, b);
  1186. if ((aa = double_float_val(a)) == 0.0) return onevalue(b);
  1187. if ((bb = double_float_val(b)) == 0.0) return onevalue(a);
  1188. if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
  1189. return aerror("VAX or 370 FP rep");
  1190. ah = top_half(aa);
  1191. bh = top_half(bb);
  1192. if (ah >= 0)
  1193. { if (bh >= 0)
  1194. { if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
  1195. }
  1196. else
  1197. { bh &= 0x7fffffff;
  1198. if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
  1199. }
  1200. }
  1201. else
  1202. { if (bh >= 0)
  1203. { ah &= 0x7fffffff;
  1204. if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
  1205. }
  1206. else
  1207. { ah &= 0x7fffffff;
  1208. bh &= 0x7fffffff;
  1209. if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
  1210. }
  1211. }
  1212. cc = aa + bb;
  1213. a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
  1214. errexit();
  1215. return onevalue(a);
  1216. }
  1217. /*
  1218. * symbolic procedure safe!-fp!-pl0(x,y);
  1219. * % protects floating plus against under-flow only.
  1220. * if zerop x then y else if zerop y then x
  1221. * else if abs x<!!plumin and abs y<!!plumin then nil else plus2(x,y);
  1222. *
  1223. * implement as safe!-fp!-pl without MUCH loss of speed.
  1224. */
  1225. static Lisp_Object Llose_precision(Lisp_Object nil,
  1226. Lisp_Object a, Lisp_Object n)
  1227. {
  1228. double aa;
  1229. char buffer[64];
  1230. int32 nn;
  1231. if (!is_float(a) || !is_fixnum(n)) return aerror2("lose_precision", a, n);
  1232. nn = int_of_fixnum(n);
  1233. if (nn <= 0 || nn >= 20) return onevalue(a);
  1234. sprintf(buffer, "%.*g", (int)nn, double_float_val(a));
  1235. if (sscanf(buffer, "%lg", &aa) != 1) return aerror("lose-precision");
  1236. a = make_boxfloat(aa, TYPE_DOUBLE_FLOAT);
  1237. errexit();
  1238. return onevalue(a);
  1239. }
  1240. setup_type const arith08_setup[] =
  1241. {
  1242. /*
  1243. * The next few are JUST for REDUCE, but they are expected to speed up
  1244. * rounded-mode arithmetic rather a lot.
  1245. */
  1246. {"lose-precision", too_few_2, Llose_precision, wrong_no_2},
  1247. {"safe-fp-plus", too_few_2, Lsafe_fp_plus, wrong_no_2},
  1248. {"safe-fp-times", too_few_2, Lsafe_fp_times, wrong_no_2},
  1249. {"safe-fp-quot", too_few_2, Lsafe_fp_quot, wrong_no_2},
  1250. {"safe-fp-pl", too_few_2, Lsafe_fp_pl, wrong_no_2},
  1251. {"safe-fp-pl0", too_few_2, Lsafe_fp_pl, wrong_no_2},
  1252. /* End of REDUCE specialities */
  1253. {"ceiling", Lceiling, Lceiling_2, wrong_no_1},
  1254. {"floor", Lfloor, Lfloor_2, wrong_no_1},
  1255. {"round", Lround, Lround_2, wrong_no_1},
  1256. {"truncate", Ltruncate, Ltruncate_2, wrong_no_1},
  1257. #ifdef COMMON
  1258. {"boole", wrong_no_na, wrong_no_nb, Lboole},
  1259. {"byte", too_few_2, Lbyte, wrong_no_2},
  1260. {"byte-position", Lbyte_position, too_many_1, wrong_no_1},
  1261. {"byte-size", Lbyte_size, too_many_1, wrong_no_1},
  1262. {"complex", Lcomplex_1, Lcomplex_2, wrong_no_2},
  1263. {"conjugate", Lconjugate, too_many_1, wrong_no_1},
  1264. {"decode-float", Ldecode_float, too_many_1, wrong_no_1},
  1265. {"float-denormalized-p", Lfloat_denormalized_p, too_many_1, wrong_no_1},
  1266. {"float-infinity-p", Lfloat_infinity_p, too_many_1, wrong_no_1},
  1267. {"denominator", Ldenominator, too_many_1, wrong_no_1},
  1268. {"deposit-field", wrong_no_na, wrong_no_nb, Ldeposit_field},
  1269. {"dpb", wrong_no_na, wrong_no_nb, Ldpb},
  1270. {"ffloor", too_few_2, Lffloor, wrong_no_2},
  1271. {"float-digits", Lfloat_digits, too_many_1, wrong_no_1},
  1272. {"float-precision", Lfloat_precision, too_many_1, wrong_no_1},
  1273. {"float-radix", Lfloat_radix, too_many_1, wrong_no_1},
  1274. {"float-sign", Lfloat_sign1, Lfloat_sign2, wrong_no_2},
  1275. {"fround", too_few_2, Lfround, wrong_no_2},
  1276. {"ftruncate", too_few_2, Lftruncate, wrong_no_2},
  1277. {"gcd", Lgcd_1, Lgcd, Lgcd_n},
  1278. {"imagpart", Limagpart, too_many_1, wrong_no_1},
  1279. {"integer-decode-float", Linteger_decode_float, too_many_1, wrong_no_1},
  1280. {"integer-length", Linteger_length, too_many_1, wrong_no_1},
  1281. {"ldb", too_few_2, Lldb, wrong_no_2},
  1282. {"ldb-test", too_few_2, Lldb_test, wrong_no_2},
  1283. {"lcm", Llcm_1, Llcm, Llcm_n},
  1284. {"logbitp", too_few_2, Llogbitp, wrong_no_2},
  1285. {"logcount", Llogcount, too_many_1, wrong_no_1},
  1286. {"logtest", too_few_2, Llogtest, wrong_no_2},
  1287. {"mask-field", too_few_2, Lmask_field, wrong_no_2},
  1288. {"numerator", Lnumerator, too_many_1, wrong_no_1},
  1289. {"realpart", Lrealpart, too_many_1, wrong_no_1},
  1290. {"scale-float", too_few_2, Lscale_float, wrong_no_2},
  1291. #else
  1292. {"fix", Ltruncate, too_many_1, wrong_no_1},
  1293. {"gcdn", too_few_2, Lgcd, wrong_no_2},
  1294. {"lcmn", too_few_2, Llcm, wrong_no_2},
  1295. #endif
  1296. {NULL, 0,0,0}
  1297. };
  1298. /* end of arith08.c */