arith12.c 18 KB

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