arith12.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. /* arith12.c Copyright (C) 1990-2002 Codemist Ltd */
  2. /*
  3. * Arithmetic functions... specials for Reduce (esp. factoriser)
  4. *
  5. */
  6. /*
  7. * This code may be used and modified, and redistributed in binary
  8. * or source form, subject to the "CCL Public License", which should
  9. * accompany it. This license is a variant on the BSD license, and thus
  10. * permits use of code derived from this in either open and commercial
  11. * projects: but it does require that updates to this code be made
  12. * available back to the originators of the package.
  13. * Before merging other code in with this or linking this code
  14. * with other packages or libraries please check that the license terms
  15. * of the other material are compatible with those of this.
  16. */
  17. /* Signature: 0d21727a 08-Apr-2002 */
  18. #define FP_EVALUATE 1
  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. #include "entries.h"
  29. #ifdef TIMEOUT
  30. #include "timeout.h"
  31. #endif
  32. Lisp_Object Lfrexp(Lisp_Object nil, Lisp_Object a)
  33. {
  34. double d;
  35. int x;
  36. d = float_of_number(a);
  37. d = frexp(d, &x);
  38. if (d == 1.0) d = 0.5, x++;
  39. a = make_boxfloat(d, TYPE_DOUBLE_FLOAT);
  40. errexit();
  41. return Lcons(nil, fixnum_of_int((int32)x), a);
  42. }
  43. Lisp_Object Lmodular_difference(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  44. {
  45. int32 r;
  46. CSL_IGNORE(nil);
  47. r = int_of_fixnum(a) - int_of_fixnum(b);
  48. if (r < 0) r += current_modulus;
  49. return onevalue(fixnum_of_int(r));
  50. }
  51. Lisp_Object Lmodular_minus(Lisp_Object nil, Lisp_Object a)
  52. {
  53. CSL_IGNORE(nil);
  54. if (a != fixnum_of_int(0))
  55. { int32 r = current_modulus - int_of_fixnum(a);
  56. a = fixnum_of_int(r);
  57. }
  58. return onevalue(a);
  59. }
  60. Lisp_Object Lmodular_number(Lisp_Object nil, Lisp_Object a)
  61. {
  62. int32 r;
  63. a = Cremainder(a, fixnum_of_int(current_modulus));
  64. errexit();
  65. r = int_of_fixnum(a);
  66. if (r < 0) r += current_modulus;
  67. return onevalue(fixnum_of_int(r));
  68. }
  69. Lisp_Object Lmodular_plus(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  70. {
  71. int32 r;
  72. CSL_IGNORE(nil);
  73. r = int_of_fixnum(a) + int_of_fixnum(b);
  74. if (r >= current_modulus) r -= current_modulus;
  75. return onevalue(fixnum_of_int(r));
  76. }
  77. Lisp_Object Lmodular_reciprocal(Lisp_Object nil, Lisp_Object n)
  78. {
  79. int32 a, b, x, y;
  80. CSL_IGNORE(nil);
  81. a = current_modulus;
  82. b = int_of_fixnum(n);
  83. x = 0;
  84. y = 1;
  85. if (b == 0) return aerror1("modular-reciprocal", n);
  86. while (b != 1)
  87. { int32 w = a / b;
  88. int32 t = b;
  89. b = a - b*w;
  90. a = t;
  91. t = y;
  92. y = x - y*w;
  93. x = t;
  94. }
  95. if (y < 0) y += current_modulus;
  96. return onevalue(fixnum_of_int(y));
  97. }
  98. Lisp_Object Lmodular_times(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  99. {
  100. unsigned32 h, l, r, cm;
  101. int32 aa, bb;
  102. CSL_IGNORE(nil);
  103. cm = (unsigned32)current_modulus;
  104. aa = int_of_fixnum(a);
  105. bb = int_of_fixnum(b);
  106. /*
  107. * The constant 46341 is sqrt(2^31) suitable rounded - if my modulus
  108. * is no bigger than that then a and b will both be strictly smaller,
  109. * and hence a*b will be < 2^31 and hence in range for 32-bit signed
  110. * arithmetic. I make this test because I expect Imultiply and Idivide
  111. * to be pretty painful, while regular C multiplication and division are
  112. * (probably!) much better.
  113. */
  114. if (cm <= 46341U) r = (aa * bb) % cm;
  115. else
  116. {
  117. #ifdef MULDIV64
  118. r = (unsigned32)(((unsigned64)aa * (unsigned64)bb) % (unsigned32)cm);
  119. #else
  120. Dmultiply(h, l, aa, bb, 0);
  121. Ddivide(r, l, h, l, cm);
  122. #endif
  123. }
  124. return onevalue(fixnum_of_int(r));
  125. }
  126. Lisp_Object Lmodular_quotient(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  127. {
  128. CSL_IGNORE(nil);
  129. push(a);
  130. b = Lmodular_reciprocal(nil, b);
  131. pop(a);
  132. errexit();
  133. return Lmodular_times(nil, a, b);
  134. }
  135. Lisp_Object Lmodular_expt(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  136. {
  137. int32 x, r, p;
  138. unsigned32 h, l;
  139. CSL_IGNORE(nil);
  140. x = int_of_fixnum(b);
  141. if (x == 0) return onevalue(fixnum_of_int(1));
  142. p = int_of_fixnum(a);
  143. /*
  144. * I could play games here on half-length current_modulus and use
  145. * native C arithmetic, but I judge this case not to be quite that
  146. * critically important. Also on 64-bit machines I could do more
  147. * work in-line.
  148. */
  149. p = p % current_modulus; /* In case somebody is being silly! */
  150. while ((x & 1) == 0)
  151. { Dmultiply(h, l, p, p, 0);
  152. Ddivide(p, l, h, l, current_modulus);
  153. x = x/2;
  154. }
  155. r = p;
  156. while (x != 1)
  157. { Dmultiply(h, l, p, p, 0);
  158. Ddivide(p, l, h, l, current_modulus);
  159. x = x/2;
  160. if ((x & 1) != 0)
  161. { Dmultiply(h, l, r, p, 0);
  162. Ddivide(r, l, h, l, current_modulus);
  163. }
  164. }
  165. return onevalue(fixnum_of_int(r));
  166. }
  167. Lisp_Object Lset_small_modulus(Lisp_Object nil, Lisp_Object a)
  168. {
  169. int32 r, old = current_modulus;
  170. CSL_IGNORE(nil);
  171. if (!is_fixnum(a)) return aerror1("set-small-modulus", a);
  172. r = int_of_fixnum(a);
  173. /*
  174. * I COULD allow a small modulus of up to 2^27, but for compatibility
  175. * with Cambridge Lisp I will limit myself to 24 bits.
  176. */
  177. if (r > 0x00ffffff) return aerror1("set-small-modulus", a);
  178. current_modulus = r;
  179. return onevalue(fixnum_of_int(old));
  180. }
  181. Lisp_Object Liadd1(Lisp_Object nil, Lisp_Object a)
  182. {
  183. CSL_IGNORE(nil);
  184. if (!is_fixnum(a)) return aerror1("iadd1", a);
  185. return onevalue((Lisp_Object)((int32)a + 0x10));
  186. }
  187. Lisp_Object Lidifference(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  188. {
  189. CSL_IGNORE(nil);
  190. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("idifference", a, b);
  191. return onevalue((Lisp_Object)((int32)a - (int32)b + TAG_FIXNUM));
  192. }
  193. /*
  194. * xdifference is provided just for the support of the CASE operator. It
  195. * subtracts its arguments but returns NIL if either argument is not
  196. * an small integer or if the result overflows.
  197. */
  198. Lisp_Object Lxdifference(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  199. {
  200. int32 r;
  201. if (!is_fixnum(a) || !is_fixnum(b)) return onevalue(nil);
  202. r = int_of_fixnum(a) - int_of_fixnum(b);
  203. if (r < -0x08000000 || r > 0x07ffffff) return onevalue(nil);
  204. return onevalue(fixnum_of_int(r));
  205. }
  206. Lisp_Object Ligreaterp(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  207. {
  208. CSL_IGNORE(nil);
  209. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("igreaterp", a, b);
  210. return onevalue(Lispify_predicate(a > b));
  211. }
  212. Lisp_Object Lilessp(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  213. {
  214. CSL_IGNORE(nil);
  215. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("ilessp", a, b);
  216. return onevalue(Lispify_predicate(a < b));
  217. }
  218. Lisp_Object Ligeq(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  219. {
  220. CSL_IGNORE(nil);
  221. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("igeq", a, b);
  222. return onevalue(Lispify_predicate(a >= b));
  223. }
  224. Lisp_Object Lileq(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  225. {
  226. CSL_IGNORE(nil);
  227. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("ileq", a, b);
  228. return onevalue(Lispify_predicate(a <= b));
  229. }
  230. static Lisp_Object MS_CDECL Lilogand(Lisp_Object nil, int nargs, ...)
  231. {
  232. va_list a;
  233. Lisp_Object r;
  234. if (nargs == 0) return onevalue(fixnum_of_int(-1));
  235. if (nargs > ARG_CUT_OFF) return aerror("too many args for ilogand");
  236. CSL_IGNORE(nil);
  237. va_start(a, nargs);
  238. r = va_arg(a, Lisp_Object);
  239. if (!is_fixnum(r)) return aerror1("ilogand", r);
  240. while (--nargs != 0)
  241. { Lisp_Object w = va_arg(a, Lisp_Object);
  242. if (!is_fixnum(w))
  243. { va_end(a);
  244. return aerror1("ilogand", w);
  245. }
  246. r = (Lisp_Object)((int32)r & (int32)w);
  247. }
  248. va_end(a);
  249. return onevalue(r);
  250. }
  251. static Lisp_Object MS_CDECL Lilogor(Lisp_Object nil, int nargs, ...)
  252. {
  253. va_list a;
  254. Lisp_Object r;
  255. if (nargs == 0) return onevalue(fixnum_of_int(0));
  256. if (nargs > ARG_CUT_OFF) return aerror("too many args for ilogor");
  257. CSL_IGNORE(nil);
  258. va_start(a, nargs);
  259. r = va_arg(a, Lisp_Object);
  260. if (!is_fixnum(r)) return aerror1("ilogor", r);
  261. while (--nargs != 0)
  262. { Lisp_Object w = va_arg(a, Lisp_Object);
  263. if (!is_fixnum(w))
  264. { va_end(a);
  265. return aerror1("ilogor", w);
  266. }
  267. r = (Lisp_Object)((int32)r | (int32)w);
  268. }
  269. va_end(a);
  270. return onevalue(r);
  271. }
  272. static Lisp_Object MS_CDECL Lilogxor(Lisp_Object nil, int nargs, ...)
  273. {
  274. va_list a;
  275. Lisp_Object r;
  276. if (nargs == 0) return onevalue(fixnum_of_int(0));
  277. if (nargs > ARG_CUT_OFF) return aerror("too many args for ilogxor");
  278. CSL_IGNORE(nil);
  279. va_start(a, nargs);
  280. r = va_arg(a, Lisp_Object);
  281. if (!is_fixnum(r)) return aerror1("ilogxor", r);
  282. while (--nargs != 0)
  283. { Lisp_Object w = va_arg(a, Lisp_Object);
  284. if (!is_fixnum(w))
  285. { va_end(a);
  286. return aerror1("ilogxor", w);
  287. }
  288. r = (Lisp_Object)(((int32)r ^ (int32)w) + TAG_FIXNUM);
  289. }
  290. va_end(a);
  291. return onevalue(r);
  292. }
  293. static Lisp_Object Lilogand2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  294. {
  295. CSL_IGNORE(nil);
  296. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("ilogand", a, b);
  297. return onevalue(a & b);
  298. }
  299. static Lisp_Object Lilogor2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  300. {
  301. CSL_IGNORE(nil);
  302. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("ilogor", a, b);
  303. return onevalue(a | b);
  304. }
  305. static Lisp_Object Lilogxor2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  306. {
  307. CSL_IGNORE(nil);
  308. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("ilogxor", a, b);
  309. return onevalue((a ^ b) + TAG_FIXNUM);
  310. }
  311. Lisp_Object Limin(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  312. {
  313. CSL_IGNORE(nil);
  314. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("imin", a, b);
  315. return onevalue(a < b ? a : b);
  316. }
  317. Lisp_Object Limax(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  318. {
  319. CSL_IGNORE(nil);
  320. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("imax", a, b);
  321. return onevalue(a > b ? a : b);
  322. }
  323. Lisp_Object Liminus(Lisp_Object nil, Lisp_Object a)
  324. {
  325. CSL_IGNORE(nil);
  326. if (!is_fixnum(a)) return aerror1("iminus", a);
  327. return onevalue((Lisp_Object)(2*TAG_FIXNUM - (int32)a));
  328. }
  329. Lisp_Object Liminusp(Lisp_Object nil, Lisp_Object a)
  330. {
  331. CSL_IGNORE(nil);
  332. return onevalue(Lispify_predicate((int32)a < (int32)fixnum_of_int(0)));
  333. }
  334. static Lisp_Object MS_CDECL Liplus(Lisp_Object nil, int nargs, ...)
  335. {
  336. va_list a;
  337. Lisp_Object r;
  338. if (nargs == 0) return onevalue(fixnum_of_int(0));
  339. if (nargs > ARG_CUT_OFF) return aerror("too many args for iplus");
  340. CSL_IGNORE(nil);
  341. va_start(a, nargs);
  342. r = va_arg(a, Lisp_Object);
  343. if (!is_fixnum(r)) return aerror1("iplus", r);
  344. while (--nargs != 0)
  345. { Lisp_Object w = va_arg(a, Lisp_Object);
  346. if (!is_fixnum(w))
  347. { va_end(a);
  348. return aerror1("iplus", w);
  349. }
  350. r = (Lisp_Object)((int32)r + (int32)w - TAG_FIXNUM);
  351. }
  352. va_end(a);
  353. return onevalue(r);
  354. }
  355. Lisp_Object Liplus2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  356. {
  357. CSL_IGNORE(nil);
  358. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("iplus2", a, b);
  359. return onevalue((Lisp_Object)((int32)a + (int32)b - TAG_FIXNUM));
  360. }
  361. Lisp_Object Liquotient(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  362. {
  363. int32 aa, bb, c;
  364. CSL_IGNORE(nil);
  365. if (!is_fixnum(a) || !is_fixnum(b) ||
  366. b == fixnum_of_int(0)) return aerror2("iquotient", a, b);
  367. /* C does not define the exact behaviour of /, % on -ve args */
  368. aa = int_of_fixnum(a);
  369. bb = int_of_fixnum(b);
  370. c = aa % bb;
  371. if (aa < 0)
  372. { if (c > 0) c -= bb;
  373. }
  374. else if (c < 0) c += bb;
  375. return onevalue(fixnum_of_int((aa-c)/bb));
  376. }
  377. Lisp_Object Liremainder(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  378. {
  379. int32 aa, bb, c;
  380. CSL_IGNORE(nil);
  381. if (!is_fixnum(a) || !is_fixnum(b) ||
  382. b == fixnum_of_int(0)) return aerror2("iremainder", a, b);
  383. /* C does not define the exact behaviour of /, % on -ve args */
  384. aa = int_of_fixnum(a);
  385. bb = int_of_fixnum(b);
  386. c = aa % bb;
  387. if (aa < 0)
  388. { if (c > 0) c -= bb;
  389. }
  390. else if (c < 0) c += bb;
  391. return onevalue(fixnum_of_int(c));
  392. }
  393. Lisp_Object Lirightshift(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  394. {
  395. CSL_IGNORE(nil);
  396. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("irightshift", a, b);
  397. return onevalue(fixnum_of_int(int_of_fixnum(a) >> int_of_fixnum(b)));
  398. }
  399. Lisp_Object Lisub1(Lisp_Object nil, Lisp_Object a)
  400. {
  401. CSL_IGNORE(nil);
  402. if (!is_fixnum(a)) return aerror1("isub1", a);
  403. return onevalue((Lisp_Object)((int32)a - 0x10));
  404. }
  405. static Lisp_Object MS_CDECL Litimes(Lisp_Object nil, int nargs, ...)
  406. {
  407. va_list a;
  408. Lisp_Object rr;
  409. int32 r;
  410. if (nargs == 0) return onevalue(fixnum_of_int(1));
  411. if (nargs > ARG_CUT_OFF) return aerror("too many args for itimes");
  412. CSL_IGNORE(nil);
  413. va_start(a, nargs);
  414. rr = va_arg(a, Lisp_Object);
  415. if (!is_fixnum(rr)) return aerror1("itimes", rr);
  416. r = int_of_fixnum(rr);
  417. while (nargs-- != 0)
  418. { Lisp_Object w = va_arg(a, Lisp_Object);
  419. if (!is_fixnum(w))
  420. { va_end(a);
  421. return aerror1("itimes", w);
  422. }
  423. r = r * int_of_fixnum(w);
  424. }
  425. va_end(a);
  426. return onevalue(fixnum_of_int(r));
  427. }
  428. Lisp_Object Litimes2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
  429. {
  430. CSL_IGNORE(nil);
  431. if (!is_fixnum(a) || !is_fixnum(b)) return aerror2("itimes2", a, b);
  432. return onevalue(fixnum_of_int(int_of_fixnum(a) * int_of_fixnum(b)));
  433. }
  434. Lisp_Object Lionep(Lisp_Object nil, Lisp_Object a)
  435. {
  436. CSL_IGNORE(nil);
  437. return onevalue(Lispify_predicate((int32)a == (int32)fixnum_of_int(1)));
  438. }
  439. Lisp_Object Lizerop(Lisp_Object nil, Lisp_Object a)
  440. {
  441. CSL_IGNORE(nil);
  442. return onevalue(Lispify_predicate((int32)a == (int32)fixnum_of_int(0)));
  443. }
  444. #ifdef FP_EVALUATE
  445. static double fp_args[32];
  446. static double fp_stack[16];
  447. /* codes 0 to 31 just load up arguments */
  448. #define FP_RETURN 32
  449. #define FP_PLUS 33
  450. #define FP_DIFFERENCE 34
  451. #define FP_TIMES 35
  452. #define FP_QUOTIENT 36
  453. #define FP_MINUS 37
  454. #define FP_SQUARE 38
  455. #define FP_CUBE 39
  456. #define FP_SIN 40
  457. #define FP_COS 41
  458. #define FP_TAN 42
  459. #define FP_EXP 43
  460. #define FP_LOG 44
  461. #define FP_SQRT 45
  462. static Lisp_Object Lfp_eval(Lisp_Object nil, Lisp_Object code,
  463. Lisp_Object args)
  464. /*
  465. * The object of this code is to support fast evaluation of numeric
  466. * expressions. The first argument is a vector of byte opcodes, while
  467. * the second arg is a list of floating point values whose value will (or
  468. * at least may) be used. There are at most 32 values in this list.
  469. */
  470. {
  471. int n = 0;
  472. double w;
  473. unsigned char *p;
  474. if (!is_vector(code)) return aerror("fp-evaluate");
  475. while (consp(args))
  476. { fp_args[n++] = float_of_number(qcar(args));
  477. args = qcdr(args);
  478. }
  479. n = 0;
  480. p = &ucelt(code, 0);
  481. for (;;)
  482. { int op = *p++;
  483. /*
  484. * Opcodes 0 to 31 just load up the corresponding input value.
  485. */
  486. if (op < 32)
  487. { fp_stack[n++] = fp_args[op];
  488. continue;
  489. }
  490. switch (op)
  491. {
  492. default:
  493. return aerror("Bad op in fp-evaluate");
  494. case FP_RETURN:
  495. args = make_boxfloat(fp_stack[0], TYPE_DOUBLE_FLOAT);
  496. errexit();
  497. return onevalue(args);
  498. case FP_PLUS:
  499. n--;
  500. fp_stack[n] += fp_stack[n-1];
  501. continue;
  502. case FP_DIFFERENCE:
  503. n--;
  504. fp_stack[n] -= fp_stack[n-1];
  505. continue;
  506. case FP_TIMES:
  507. n--;
  508. fp_stack[n] *= fp_stack[n-1];
  509. continue;
  510. case FP_QUOTIENT:
  511. n--;
  512. fp_stack[n] /= fp_stack[n-1];
  513. continue;
  514. case FP_MINUS:
  515. fp_stack[n] = -fp_stack[n];
  516. continue;
  517. case FP_SQUARE:
  518. fp_stack[n] *= fp_stack[n];
  519. continue;
  520. case FP_CUBE:
  521. w = fp_stack[n];
  522. w *= w;
  523. fp_stack[n] *= w;
  524. continue;
  525. case FP_SIN:
  526. fp_stack[n] = sin(fp_stack[n]);
  527. continue;
  528. case FP_COS:
  529. fp_stack[n] = cos(fp_stack[n]);
  530. continue;
  531. case FP_TAN:
  532. fp_stack[n] = tan(fp_stack[n]);
  533. continue;
  534. case FP_EXP:
  535. fp_stack[n] = exp(fp_stack[n]);
  536. continue;
  537. case FP_LOG:
  538. fp_stack[n] = log(fp_stack[n]);
  539. continue;
  540. case FP_SQRT:
  541. fp_stack[n] = sqrt(fp_stack[n]);
  542. continue;
  543. }
  544. }
  545. }
  546. #endif
  547. setup_type const arith12_setup[] =
  548. {
  549. {"frexp", Lfrexp, too_many_1, wrong_no_1},
  550. {"modular-difference", too_few_2, Lmodular_difference, wrong_no_2},
  551. {"modular-minus", Lmodular_minus, too_many_1, wrong_no_1},
  552. {"modular-number", Lmodular_number, too_many_1, wrong_no_1},
  553. {"modular-plus", too_few_2, Lmodular_plus, wrong_no_2},
  554. {"modular-quotient", too_few_2, Lmodular_quotient, wrong_no_2},
  555. {"modular-reciprocal", Lmodular_reciprocal, too_many_1, wrong_no_1},
  556. {"modular-times", too_few_2, Lmodular_times, wrong_no_2},
  557. {"modular-expt", too_few_2, Lmodular_expt, wrong_no_2},
  558. {"set-small-modulus", Lset_small_modulus, too_many_1, wrong_no_1},
  559. {"iadd1", Liadd1, too_many_1, wrong_no_1},
  560. {"idifference", too_few_2, Lidifference, wrong_no_2},
  561. {"xdifference", too_few_2, Lxdifference, wrong_no_2},
  562. {"igeq", too_few_2, Ligeq, wrong_no_2},
  563. {"igreaterp", too_few_2, Ligreaterp, wrong_no_2},
  564. {"ileq", too_few_2, Lileq, wrong_no_2},
  565. {"ilessp", too_few_2, Lilessp, wrong_no_2},
  566. {"ilogand", Lidentity, Lilogand2, Lilogand},
  567. {"ilogor", Lidentity, Lilogor2, Lilogor},
  568. {"ilogxor", Lidentity, Lilogxor2, Lilogxor},
  569. {"imax", too_few_2, Limax, wrong_no_2},
  570. {"imin", too_few_2, Limin, wrong_no_2},
  571. {"iminus", Liminus, too_many_1, wrong_no_1},
  572. {"iminusp", Liminusp, too_many_1, wrong_no_1},
  573. {"iplus", Lidentity, Liplus2, Liplus},
  574. {"iplus2", too_few_2, Liplus2, wrong_no_2},
  575. {"iquotient", too_few_2, Liquotient, wrong_no_2},
  576. {"iremainder", too_few_2, Liremainder, wrong_no_2},
  577. {"irightshift", too_few_2, Lirightshift, wrong_no_2},
  578. {"isub1", Lisub1, too_many_1, wrong_no_1},
  579. {"itimes", Lidentity, Litimes2, Litimes},
  580. {"itimes2", too_few_2, Litimes2, wrong_no_2},
  581. {"ionep", Lionep, too_many_1, wrong_no_1},
  582. {"izerop", Lizerop, too_many_1, wrong_no_1},
  583. #ifdef FP_EVALUATE
  584. {"fp-evaluate", too_few_2, Lfp_eval, wrong_no_2},
  585. #endif
  586. {NULL, 0, 0, 0}
  587. };
  588. /* end of arith12.c */