123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380 |
- /* arith08.c Copyright (C) 1990-95 Codemist Ltd */
- /*
- * Arithmetic functions.
- */
- /* Signature: 02ccc991 07-Mar-2000 */
- #include <stdarg.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
- #include <float.h>
- #include "machine.h"
- #include "tags.h"
- #include "cslerror.h"
- #include "externs.h"
- #include "arith.h"
- #include "entries.h"
- #ifdef TIMEOUT
- #include "timeout.h"
- #endif
- #ifdef COMMON
- static Lisp_Object MS_CDECL Lboole(Lisp_Object nil, int nargs, ...)
- {
- Lisp_Object r, op, a, b;
- va_list aa;
- argcheck(nargs, 3, "boole");
- va_start(aa, nargs);
- op = va_arg(aa, Lisp_Object);
- a = va_arg(aa, Lisp_Object);
- b = va_arg(aa, Lisp_Object);
- va_end(aa);
- switch (op)
- {
- case fixnum_of_int(boole_clr):
- return onevalue(fixnum_of_int(0));
- case fixnum_of_int(boole_and):
- r = logand2(a, b);
- break;
- case fixnum_of_int(boole_andc2):
- push(a);
- b = lognot(b);
- pop(a);
- errexit();
- r = logand2(a, b);
- break;
- case fixnum_of_int(boole_1):
- return onevalue(a);
- case fixnum_of_int(boole_andc1):
- push(b);
- a = lognot(a);
- pop(b);
- errexit();
- r = logand2(a, b);
- break;
- case fixnum_of_int(boole_2):
- return onevalue(b);
- case fixnum_of_int(boole_xor):
- r = logxor2(a, b);
- break;
- case fixnum_of_int(boole_ior):
- r = logior2(a, b);
- break;
- case fixnum_of_int(boole_nor):
- a = logior2(a, b);
- errexit();
- r = lognot(a);
- break;
- case fixnum_of_int(boole_eqv):
- r = logeqv2(a, b);
- break;
- case fixnum_of_int(boole_c2):
- r = lognot(b);
- break;
- case fixnum_of_int(boole_orc2):
- b = lognot(b);
- errexit();
- r = logior2(a, b);
- break;
- case fixnum_of_int(boole_c1):
- r = lognot(a);
- break;
- case fixnum_of_int(boole_orc1):
- push(b);
- a = lognot(a);
- pop(b);
- errexit();
- r = logior2(a, b);
- break;
- case fixnum_of_int(boole_nand):
- a = logand2(a, b);
- errexit();
- r = lognot(a);
- break;
- case fixnum_of_int(boole_set):
- return onevalue(fixnum_of_int(-1));
- default:
- return aerror1("bad arg for boole", op);
- }
- errexit();
- return onevalue(r);
- }
- static Lisp_Object Lbyte(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- a = cons(a, b);
- errexit();
- return onevalue(a);
- }
- static Lisp_Object Lbyte_position(Lisp_Object nil, Lisp_Object a)
- {
- if (!consp(a)) return aerror1("byte-position", a);
- else return onevalue(qcdr(a));
- }
- static Lisp_Object Lbyte_size(Lisp_Object nil, Lisp_Object a)
- {
- if (!consp(a)) return aerror1("byte-size", a);
- else return onevalue(qcar(a));
- }
- static Lisp_Object Lcomplex_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- /* /* Need to coerce a and b to the same type here... */
- a = make_complex(a, b);
- errexit();
- return onevalue(a);
- }
- static Lisp_Object Lcomplex_1(Lisp_Object nil, Lisp_Object a)
- {
- /* /* Need to make zero of same type as a */
- a = make_complex(a, fixnum_of_int(0));
- errexit();
- return onevalue(a);
- }
- static Lisp_Object Lconjugate(Lisp_Object nil, Lisp_Object a)
- {
- if (!is_number(a)) return aerror1("conjugate", a);
- if (is_numbers(a) && is_complex(a))
- { Lisp_Object r = real_part(a),
- i = imag_part(a);
- push(r);
- i = negate(i);
- pop(r);
- errexit();
- a = make_complex(r, i);
- errexit();
- return onevalue(a);
- }
- else return onevalue(a);
- }
- static Lisp_Object Ldecode_float(Lisp_Object nil, Lisp_Object a)
- {
- double d = float_of_number(a), neg = 1.0;
- int x;
- Lisp_Object sign;
- if (!is_float(a)) return aerror("decode-float");
- if (d < 0.0) d = -d, neg = -1.0;
- if (d == 0.0) x = 0;
- else
- { d = frexp(d, &x);
- if (d == 1.0) d = 0.5, x++;
- }
- if (is_sfloat(a)) sign = make_sfloat(neg);
- else sign = make_boxfloat(neg, type_of_header(flthdr(a)));
- errexit();
- push(sign);
- if (is_sfloat(a)) a = make_sfloat(d);
- else a = make_boxfloat(d, type_of_header(flthdr(a)));
- pop(sign);
- errexit();
- mv_2 = fixnum_of_int(x);
- mv_3 = sign;
- return nvalues(a, 3);
- }
- /*
- * The next two functions depend on IEEE-format floating point numbers.
- * They are (thus?) potentially a portability trap, but may suffice for
- * MOST systems. I need to test the handling of double precision values
- * on computers that store the two words of a double in each of the
- * possible orders. If the exponent field in floats was not stored in the
- * position that would be 0x7f800000 in an integer my treatment of short
- * floats would fail, so I have already assumed that that is so. I think.
- */
- static Lisp_Object Lfloat_denormalized_p(Lisp_Object nil, Lisp_Object a)
- {
- int x = 0;
- switch ((int)a & TAG_BITS)
- {
- #ifdef COMMON
- case TAG_SFLOAT:
- if ((a & 0x7fffffff) == TAG_SFLOAT) return onevalue(nil); /* 0.0 */
- x = (int32)a & 0x7f800000;
- return onevalue(x == 0 ? lisp_true : nil);
- #endif
- case TAG_BOXFLOAT:
- switch (type_of_header(flthdr(a)))
- {
- #ifdef COMMON
- case TYPE_SINGLE_FLOAT:
- if (single_float_val(a) == 0.0) return onevalue(nil);
- x = ((Single_Float *)((char *)a-TAG_BOXFLOAT))->f.i & 0x7f800000;
- return onevalue(x == 0 ? lisp_true : nil);
- case TYPE_LONG_FLOAT:
- if (long_float_val(a) == 0.0) return onevalue(nil);
- x = ((Long_Float *)((char *)a-TAG_BOXFLOAT)
- )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
- return onevalue(x == 0 ? lisp_true : nil);
- #endif
- case TYPE_DOUBLE_FLOAT:
- if (double_float_val(a) == 0.0) return onevalue(nil);
- x = ((Double_Float *)((char *)a-TAG_BOXFLOAT)
- )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
- return onevalue(x == 0 ? lisp_true : nil);
- }
- default:
- break;
- }
- return onevalue(nil);
- }
- static Lisp_Object Lfloat_infinity_p(Lisp_Object nil, Lisp_Object a)
- {
- /*
- * The issue of NaN values is one I do not want to worry about at present.
- * I deem anything with the largest possibl exponent value to be infinite.
- */
- int x = 0;
- switch ((int)a & TAG_BITS)
- {
- #ifdef COMMON
- case TAG_SFLOAT:
- x = (int32)a & 0x7f800000;
- return onevalue(x == 0x7f800000 ? lisp_true : nil);
- #endif
- case TAG_BOXFLOAT:
- switch (type_of_header(flthdr(a)))
- {
- #ifdef COMMON
- case TYPE_SINGLE_FLOAT:
- if (single_float_val(a) == 0.0) return onevalue(nil);
- x = ((Single_Float *)((char *)a-TAG_BOXFLOAT))->f.i & 0x7f800000;
- return onevalue(x == 0x7f800000 ? lisp_true : nil);
- case TYPE_LONG_FLOAT:
- if (long_float_val(a) == 0.0) return onevalue(nil);
- x = ((Long_Float *)((char *)a-TAG_BOXFLOAT)
- )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
- return onevalue(x == 0x7ff00000 ? lisp_true : nil);
- #endif
- case TYPE_DOUBLE_FLOAT:
- if (double_float_val(a) == 0.0) return onevalue(nil);
- x = ((Double_Float *)((char *)a-TAG_BOXFLOAT)
- )->f.i[current_fp_rep&FP_WORD_ORDER ? 0 : 1] & 0x7ff00000;
- return onevalue(x == 0x7ff00000 ? lisp_true : nil);
- }
- default:
- break;
- }
- return onevalue(nil);
- }
- static Lisp_Object Ldenominator(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("denominator", a);
- if (is_numbers(a) && is_ratio(a))
- return onevalue(denominator(a));
- else return onevalue(fixnum_of_int(1));
- }
- static Lisp_Object MS_CDECL Ldeposit_field(Lisp_Object nil, int nargs, ...)
- {
- va_list aa;
- Lisp_Object a, b, c;
- CSL_IGNORE(nil);
- CSL_IGNORE(nargs);
- va_start(aa, nargs);
- a = va_arg(aa, Lisp_Object);
- b = va_arg(aa, Lisp_Object);
- c = va_arg(aa, Lisp_Object);
- va_end(aa);
- return aerror("deposit-field");
- }
- static Lisp_Object MS_CDECL Ldpb(Lisp_Object nil, int nargs, ...)
- {
- va_list aa;
- Lisp_Object a, b, c;
- CSL_IGNORE(nil);
- CSL_IGNORE(nargs);
- va_start(aa, nargs);
- a = va_arg(aa, Lisp_Object);
- b = va_arg(aa, Lisp_Object);
- c = va_arg(aa, Lisp_Object);
- va_end(aa);
- return aerror("dpb");
- }
- static Lisp_Object Lffloor(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("ffloor");
- }
- /*
- * The functions such as float-digits, float-precision, float-radix are
- * coded here assuming that IEEE-style arithmetic is being used. If this is
- * not so then all the code in this file needs review. Furthermore I will
- * be lazy about NaNs and denormalised numbers for now and come back to
- * worry about them later on if I am really forced to.
- */
- static Lisp_Object Lfloat_digits(Lisp_Object nil, Lisp_Object a)
- {
- int tag = (int)a & TAG_BITS;
- CSL_IGNORE(nil);
- switch (tag)
- {
- #ifdef COMMON
- case TAG_SFLOAT:
- return onevalue(fixnum_of_int(20));
- #endif
- case TAG_BOXFLOAT:
- switch (type_of_header(flthdr(a)))
- {
- #ifdef COMMON
- case TYPE_SINGLE_FLOAT:
- return onevalue(fixnum_of_int(24));
- #endif
- default:
- return onevalue(fixnum_of_int(53));
- }
- default:
- return aerror("float-digits");
- }
- }
- static Lisp_Object Lfloat_precision(Lisp_Object nil, Lisp_Object a)
- {
- int tag = (int)a & TAG_BITS;
- double d = float_of_number(a);
- CSL_IGNORE(nil);
- if (d == 0.0) return onevalue(fixnum_of_int(0));
- /* /* I do not cope with de-normalised numbers here */
- switch (tag)
- {
- #ifdef COMMON
- case TAG_SFLOAT:
- return onevalue(fixnum_of_int(20));
- #endif
- case TAG_BOXFLOAT:
- switch (type_of_header(flthdr(a)))
- {
- #ifdef COMMON
- case TYPE_SINGLE_FLOAT:
- return onevalue(fixnum_of_int(24));
- #endif
- default:
- return onevalue(fixnum_of_int(53));
- }
- default:
- return aerror("float-precision");
- }
- }
- static Lisp_Object Lfloat_radix(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- return onevalue(fixnum_of_int(FLT_RADIX));
- }
- static Lisp_Object Lfloat_sign2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- double d = float_of_number(b);
- CSL_IGNORE(nil);
- if (float_of_number(a) < 0.0) d = -d;
- if (is_sfloat(b)) return onevalue(make_sfloat(d));
- else if (!is_bfloat(b)) return aerror1("bad arg for float-sign", b);
- else return onevalue(make_boxfloat(d, type_of_header(flthdr(b))));
- }
- static Lisp_Object Lfloat_sign1(Lisp_Object nil, Lisp_Object a)
- {
- double d = float_of_number(a);
- CSL_IGNORE(nil);
- if (d < 0.0) d = -1.0; else d = 1.0;
- if (is_sfloat(a)) return onevalue(make_sfloat(d));
- else if (!is_bfloat(a)) return aerror1("bad arg for float-sign", a);
- else return onevalue(make_boxfloat(d, type_of_header(flthdr(a))));
- }
- static Lisp_Object Lfround(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("fround");
- }
- static Lisp_Object Lftruncate(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("ftruncate");
- }
- Lisp_Object MS_CDECL Lgcd_n(Lisp_Object nil, int nargs, ...)
- {
- va_list a;
- int i;
- Lisp_Object r;
- if (nargs == 0) return fixnum_of_int(0);
- va_start(a, nargs);
- push_args(a, nargs);
- /*
- * The actual args have been passed a C args - I can not afford to
- * risk garbage collection until they have all been moved somewhere safe,
- * and here that safe place is the Lisp stack. I have to delay checking for
- * overflow on same until all args have been pushed.
- */
- stackcheck0(nargs);
- pop(r);
- for (i = 1; i<nargs; i++)
- { Lisp_Object w;
- if (r == fixnum_of_int(1))
- { popv(nargs-i);
- break;
- }
- pop(w);
- r = gcd(r, w);
- errexitn(nargs-i-1);
- }
- return onevalue(r);
- }
- Lisp_Object Lgcd(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- a = gcd(a, b);
- errexit();
- return onevalue(a);
- }
- Lisp_Object Lgcd_1(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- return onevalue(a);
- }
- static Lisp_Object Limagpart(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("imagpart", a);
- if (is_numbers(a) && is_complex(a))
- return onevalue(imag_part(a));
- /* /* the 0.0 returned here ought to be the same type as a has */
- else return onevalue(fixnum_of_int(0));
- }
- static Lisp_Object Linteger_decode_float(Lisp_Object nil, Lisp_Object a)
- {
- double d = float_of_number(a);
- int tag = (int)a & TAG_BITS, x, neg = 0;
- int32 a1, a2;
- CSL_IGNORE(nil);
- if (!is_float(a)) return aerror("integer-decode-float");
- if (d == 0.0)
- #ifdef COMMON
- { mv_2 = fixnum_of_int(0);
- mv_3 = fixnum_of_int(1);
- nvalues(a, 3);
- }
- #else
- return list3(a, fixnum_of_int(0), fixnum_of_int(1));
- #endif
- if (d < 0.0) d = -d, neg = 1;
- d = frexp(d, &x);
- if (d == 1.0) d = 0.5, x++;
- #ifdef COMMON
- if (tag == TAG_SFLOAT)
- { d *= TWO_20;
- x -= 20;
- a1 = (int32)d;
- a = fixnum_of_int(a1);
- }
- else if (tag == TAG_BOXFLOAT &&
- type_of_header(flthdr(a)) == TYPE_SINGLE_FLOAT)
- { d *= TWO_24;
- x -= 24;
- a1 = (int32)d;
- a = fixnum_of_int(a1);
- }
- else
- #endif
- { d *= TWO_22;
- a1 = (int32)d;
- d -= (double)a1;
- a2 = (int32)(d*TWO_31); /* This conversion should be exact */
- x -= 53;
- a = make_two_word_bignum(a1, a2);
- errexit();
- }
- #ifdef COMMON
- { mv_2 = fixnum_of_int(x);
- mv_3 = neg ? fixnum_of_int(-1) : fixnum_of_int(1);
- return nvalues(a, 3);
- }
- #else
- return list3(a, fixnum_of_int(x),
- neg ? fixnum_of_int(-1) : fixnum_of_int(1));
- #endif
- }
- static Lisp_Object Linteger_length(Lisp_Object nil, Lisp_Object a)
- {
- a = Labsval(nil, a);
- errexit();
- return Lmsd(nil, a);
- }
- static Lisp_Object Lldb(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("ldb");
- }
- Lisp_Object MS_CDECL Llcm_n(Lisp_Object nil, int nargs, ...)
- {
- va_list a;
- int i;
- Lisp_Object r;
- if (nargs == 0) return onevalue(fixnum_of_int(1));
- va_start(a, nargs);
- push_args(a, nargs);
- stackcheck0(nargs);
- pop(r);
- for (i = 1; i<nargs; i++)
- { Lisp_Object w;
- pop(w);
- r = lcm(r, w);
- errexitn(nargs-i-1);
- }
- return onevalue(r);
- }
- Lisp_Object Llcm(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- a = lcm(a, b);
- errexit();
- return onevalue(a);
- }
- Lisp_Object Llcm_1(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- return onevalue(a);
- }
- static Lisp_Object Lldb_test(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("ldb-test");
- }
- static Lisp_Object Llogbitp(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("logbitp");
- }
- static Lisp_Object Llogcount(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- return aerror("logcount");
- }
- static Lisp_Object Llogtest(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("logtest");
- }
- static Lisp_Object Lmask_field(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- CSL_IGNORE(a);
- CSL_IGNORE(b);
- return aerror("mask-field");
- }
- static Lisp_Object Lnumerator(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("numerator", a);
- if (is_numbers(a) && is_ratio(a))
- return onevalue(numerator(a));
- else return onevalue(a);
- }
- static Lisp_Object Lrealpart(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("realpart", a);
- if (is_numbers(a) && is_complex(a))
- return onevalue(real_part(a));
- else return onevalue(a);
- }
- static Lisp_Object Lscale_float(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- double d = float_of_number(a);
- CSL_IGNORE(nil);
- if (!is_fixnum(b)) return aerror("scale-float");
- d = ldexp(d, int_of_fixnum(b));
- if (is_sfloat(a)) return onevalue(make_sfloat(d));
- else if (!is_bfloat(a)) return aerror1("bad arg for scale-float", a);
- else return onevalue(make_boxfloat(d, type_of_header(flthdr(a))));
- }
- #else /* COMMON */
- Lisp_Object Lgcd(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- a = gcd(a, b);
- errexit();
- return onevalue(a);
- }
- Lisp_Object Llcm(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- Lisp_Object g;
- push2(b, a);
- g = gcd(a, b);
- errexitn(2);
- pop(a);
- a = quot2(a, g);
- pop(b);
- errexit();
- a = times2(a, b);
- errexit();
- return onevalue(a);
- }
- #endif /* COMMON */
- #define FIX_TRUNCATE 0
- #define FIX_ROUND 1
- #define FIX_FLOOR 2
- #define FIX_CEILING 3
- static Lisp_Object lisp_fix_sub(Lisp_Object a, int roundmode)
- /*
- * This converts from a double to a Lisp integer, which will
- * quite often have to be a bignum. No overflow is permitted - the
- * result can always be accurate.
- */
- {
- int32 a0, a1, a2, a3;
- int x, x1;
- CSLbool negative;
- double d = float_of_number(a);
- if (M2_31_1 < d && d < TWO_31)
- { int32 a = (int32)d;
- /*
- * If my floating point value is in the range -(2^31+1) to +2^31 (exclusive)
- * then when C truncates it I will get an integer in the inclusive range
- * from -2^31 to 2^31-1, i.e. the whole range of C 32-bit integers.
- * If I then apply a rounding mode other than truncation I may just have
- * overflow, which I have to detect specially.
- */
- int32 w;
- double f;
- switch (roundmode)
- {
- case FIX_TRUNCATE:
- break; /* C casts truncate, so this is OK */
- case FIX_ROUND:
- f = d - (double)a;
- if (f > 0.5)
- { if (a == 0x7fffffff) return make_two_word_bignum(1, 0);
- else a++;
- }
- else if (f < -0.5)
- { if (a == ~0x7fffffff)
- return make_two_word_bignum(-2, 0x7fffffff);
- else a--;
- }
- /* The rounding rule on the next lines show what I do in 1/2ulp cases */
- else if (f == 0.5) a = (a+1) & ~1;
- else if (f == -0.5)
- { if (a == ~0x7fffffff)
- return make_two_word_bignum(-2, 0x7fffffff);
- else a = a & ~1;
- }
- break;
- case FIX_FLOOR:
- f = d - (double)a;
- if (f < 0.0)
- { if (a == ~0x7fffffff)
- return make_two_word_bignum(-2, 0x7fffffff);
- else a--;
- }
- break;
- case FIX_CEILING:
- f = d - (double)a;
- if (f > 0.0)
- { if (a == 0x7fffffff) return make_two_word_bignum(1, 0);
- else a++;
- }
- break;
- }
- w = a & fix_mask;
- if (w == 0 || w == fix_mask) return fixnum_of_int(a);
- else if (!signed_overflow(a)) return make_one_word_bignum(a);
- else if (a > 0) return make_two_word_bignum(0, a);
- else return make_two_word_bignum(-1, clear_top_bit(a));
- }
- if (d < 0.0) d = -d, negative = YES;
- else negative = NO;
- d = frexp(d, &x); /* 0.5 <= abs(d) < 1.0, x = the (binary) exponent */
- if (d == 1.0) d = 0.5, x++;
- d *= TWO_31;
- a1 = (int32)d; /* 2^31 > d >= 2^30 */
- d -= (double)a1;
- a2 = (unsigned32)(d*TWO_31); /* This conversion should be exact */
- if (negative)
- { if (a2 == 0) a1 = -a1;
- else a2 = clear_top_bit(-a2), a1 = ~a1;
- }
- x -= 62;
- if (x < 0) /* Need to shift right x places */
- { x = -x; /* The shift amount here can be 31 at most... */
- a3 = a2 << (32 - x);
- a2 = clear_top_bit((a2 >> x) | (a1 << (31 - x)));
- #ifdef SIGNED_SHIFTS_ARE_LOGICAL
- if (a1 < 0) a1 = (a1 >> x) | (((int32)-1) << (31 - x));
- else a1 = a1 >> x;
- #else
- a1 = a1 >> x;
- #endif
- switch (roundmode)
- {
- case FIX_TRUNCATE:
- if (a1 < 0 && a3 != 0) /* proper rounding on -ve values */
- { a2++;
- if (a2 < 0) /* carry */
- { a2 = 0;
- a1++;
- }
- }
- break;
- case FIX_ROUND:
- if ((a3 & 0x80000000U) != 0 &&
- (a3 != ~0x7fffffff || (a2 & 1) != 0))
- { a2++;
- if (a2 < 0) /* carry */
- { a2 = 0;
- a1++;
- }
- }
- break;
- case FIX_FLOOR: /* Comes out in wash of 2's complement */
- break;
- case FIX_CEILING:
- if (a3 != 0)
- { a2++;
- if (a2 < 0) /* carry */
- { a2 = 0;
- a1++;
- }
- }
- break;
- }
- return make_two_word_bignum(a1, a2);
- }
- /* Now the double-length value (a1,a2) is correct and exact, and it
- * needs shifting left by x bits. This will give a 3 or more word bignum.
- * Note that no rounding etc is needed at all here since there are no
- * fractional bits in the representation.
- */
- if (a1 < 0)
- { a0 = -1;
- a1 = clear_top_bit(a1);
- }
- else a0 = 0;
- x1 = x / 31;
- x = x % 31;
- a0 = (a0 << x) | (a1 >> (31-x));
- a1 = clear_top_bit(a1 << x) | (a2 >> (31-x));
- a2 = clear_top_bit(a2 << x);
- return make_n_word_bignum(a0, a1, a2, x1);
- }
- #ifdef COMMON
- static Lisp_Object lisp_fix_ratio(Lisp_Object a, int roundmode)
- /*
- * This converts from a ratio to a Lisp integer. It has to apply
- * the specified rounding regime.
- */
- {
- Lisp_Object p, q, r, nil = C_nil;;
- p = numerator(a);
- q = denominator(a);
- push2(q, p);
- r = quot2(p, q);
- errexitn(2);
- p = stack[0];
- stack[0] = r;
- p = Cremainder(p, stack[-1]);
- pop2(r, q);
- errexit();
- switch (roundmode)
- {
- case FIX_TRUNCATE:
- break;
- case FIX_ROUND:
- /* /* This case unfinished at present */
- break;
- case FIX_FLOOR:
- if (minusp(p))
- { push(r);
- p = plus2(p, q);
- pop(r);
- errexit();
- r = sub1(r);
- errexit();
- }
- break;
- case FIX_CEILING:
- if (plusp(p))
- { push(r);
- p = difference2(p, q);
- pop(r);
- errexit();
- r = add1(r);
- errexit();
- }
- break;
- }
- mv_2 = p;
- return nvalues(r, 2);
- }
- #endif
- static Lisp_Object lisp_fix(Lisp_Object a, int roundmode)
- {
- Lisp_Object r, nil;
- push(a);
- r = lisp_fix_sub(a, roundmode);
- errexitn(1);
- a = stack[0];
- stack[0] = r;
- a = difference2(a, r);
- pop(r);
- errexit();
- mv_2 = a;
- return nvalues(r, 2);
- }
- static Lisp_Object lisp_ifix(Lisp_Object a, Lisp_Object b, int roundmode)
- {
- Lisp_Object q, r, nil;
- if (is_float(a) || is_float(b))
- { double p = float_of_number(a), q = float_of_number(b), d = p/q;
- a = make_boxfloat(d, TYPE_DOUBLE_FLOAT);
- errexit();
- r = lisp_fix(a, roundmode);
- errexit();
- push(r);
- a = make_boxfloat(float_of_number(mv_2)*q, TYPE_DOUBLE_FLOAT);
- pop(r);
- errexit();
- mv_2 = a;
- return nvalues(r, 2);
- }
- push2(a, b);
- q = quot2(a, b);
- errexitn(2);
- a = stack[-1];
- b = stack[0];
- push(q);
- r = Cremainder(a, b);
- errexitn(3);
- switch (roundmode)
- {
- case FIX_TRUNCATE:
- break;
- case FIX_ROUND:
- popv(3); return aerror("two-arg ROUND");
- case FIX_FLOOR:
- if (!minusp(r)) break;
- r = plus2(r, stack[-1]);
- errexitn(3);
- q = stack[0];
- push(r);
- q = sub1(q);
- pop(r);
- errexitn(3);
- stack[0] = q;
- break;
- case FIX_CEILING:
- if (!plusp(r)) break;
- r = difference2(r, stack[-1]);
- errexitn(3);
- q = stack[0];
- push(r);
- q = add1(q);
- pop(r);
- errexitn(3);
- stack[0] = q;
- break;
- }
- pop3(q, b, a);
- mv_2 = r;
- return nvalues(q, 2);
- }
- /*
- * So far I have not implemented support for rational numbers in the 2-arg
- * versions of these functions. /*
- */
- static Lisp_Object Lceiling_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- if (!is_number(a) || !is_number(b)) return aerror1("ceiling", a);
- return lisp_ifix(a, b, FIX_CEILING);
- }
- static Lisp_Object Lfloor_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- if (!is_number(a) || !is_number(b)) return aerror1("floor", a);
- return lisp_ifix(a, b, FIX_FLOOR);
- }
- static Lisp_Object Lround_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- if (!is_number(a) || !is_number(b)) return aerror1("round", a);
- return lisp_ifix(a, b, FIX_ROUND);
- }
- Lisp_Object Ltruncate_2(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- CSL_IGNORE(nil);
- if (!is_number(a) || !is_number(b)) return aerror1("truncate", a);
- return lisp_ifix(a, b, FIX_TRUNCATE);
- }
- static Lisp_Object Lceiling(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("ceiling", a);
- #ifdef COMMON
- if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_CEILING);
- #endif
- if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
- return lisp_fix(a, FIX_CEILING);
- }
- static Lisp_Object Lfloor(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("floor", a);
- #ifdef COMMON
- if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_FLOOR);
- #endif
- if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
- return lisp_fix(a, FIX_FLOOR);
- }
- static Lisp_Object Lround(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("round", a);
- #ifdef COMMON
- if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_ROUND);
- #endif
- if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
- return lisp_fix(a, FIX_ROUND);
- }
- Lisp_Object Ltruncate(Lisp_Object nil, Lisp_Object a)
- {
- CSL_IGNORE(nil);
- if (!is_number(a)) return aerror1("fix", a);
- #ifdef COMMON
- if (is_numbers(a) && is_ratio(a)) return lisp_fix_ratio(a, FIX_TRUNCATE);
- #endif
- if (!is_float(a)) { mv_2 = fixnum_of_int(0); return nvalues(a, 2); }
- return lisp_fix(a, FIX_TRUNCATE);
- }
- /*
- * The following macro is expected to select out the 32-bit word within a
- * floating point number that has the exponent field packed within it.
- * On IEEE-format machines I expect to find the exponent in the
- * 0x7ff00000 bits within this word.
- */
- #define top_half(d) ((int32 *)&(d))[(~current_fp_rep) & FP_WORD_ORDER]
- /*
- * symbolic procedure safe!-fp!-plus(x,y);
- * if zerop x then y else if zerop y then x else
- * begin scalar u;
- * if x>0.0 and y>0.0 then
- * if x<!!plumax and y<!!plumax then go to ret else return nil;
- * if x<0.0 and y<0.0 then
- * if -x<!!plumax and -y<!!plumax then go to ret else return nil;
- * if abs x<!!plumin and abs y<!!plumin then return nil;
- * ret: return
- * if (u := plus2(x,y))=0.0
- * or x>0.0 and y>0.0 or x<0.0 and y<0.0 then u
- * else if abs u<(abs x)*!!fleps1 then 0.0 else u end;
- */
- static Lisp_Object Lsafe_fp_plus(Lisp_Object env, Lisp_Object a, Lisp_Object b)
- /*
- * safe!-fp!-plus must always be given floating point arguments. In
- * most reasonable cases it just returns the floating point sum. If
- * there was some chance that the sum might either overflow or underflow
- * then the value NIL is returned instead. The exact place where this
- * function starts to report overflow is not precisely defined - all that
- * is guaranteed is that if a result is returned then it will be of full
- * precision.
- */
- {
- Lisp_Object nil = C_nil;
- double aa, bb, cc;
- int32 ah, bh;
- if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-plus", a, b);
- /*
- * I accept here that adding 0.0 to anything is always possible without
- * problem.
- */
- if ((aa = double_float_val(a)) == 0.0) return onevalue(b);
- if ((bb = double_float_val(b)) == 0.0) return onevalue(a);
- if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
- return aerror("VAX or 370 FP rep");
- ah = top_half(aa);
- bh = top_half(bb);
- /*
- * Here I am going to assume IEEE-format numbers. I hope that I have
- * picked out the word containing the exponent and that it is positioned in
- * the word where I expect.
- */
- /*
- * I deem overflow POSSIBLE if both numbers have the same sign and if at
- * least one of them has an exponent 0x7fe (i.e. the highest exponent that
- * a non-infinite number can have).
- */
- if (ah >= 0)
- { if (bh >= 0)
- { if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
- cc = aa + bb;
- }
- else
- /*
- * I deem underflow POSSIBLE if the numbers have opposite signs and BOTH
- * of them have exponents less than 0x035 (which is 53 in decimal, and
- * IEEE-format numbers have 53-bit mantissas. The critical case would
- * be the subtraction
- * (53) 1 00000000000000000000 00000000000000000000000000000001
- * - (53) 1 00000000000000000000 00000000000000000000000000000000
- * where you see the LSB (which is all that is left after the subtraction)
- * has to be shifted left 52 bits to get to the position of the implied
- * leading 1 bit in the mantissa. As that happens 52 gets subtracted
- * from the exponent, leaving it as 1, the smallest exponent for a normalised
- * non-zero value.
- */
- { double eps, ra;
- bh &= 0x7fffffff;
- if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
- /*
- * The next few lines check to see if addition has led to cancellation of
- * leading digits to an extent greater than !!fleps1. The environent cell
- * of safe!-fp!-plus must be set to !!fleps, and then the value cell of
- * this symbol is accessed to obtain the limit.
- */
- eps = 0.0;
- if (is_symbol(env))
- { Lisp_Object ve = qvalue(env);
- if (is_float(ve)) eps = double_float_val(ve);
- }
- cc = aa + bb;
- ra = cc/aa;
- if (ra < 0.0) ra = -ra;
- if (ra < eps) cc = 0.0; /* Force to zero if too small */
- }
- }
- else
- { if (bh >= 0)
- { double eps, ra;
- ah &= 0x7fffffff;
- if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
- eps = 0.0;
- if (is_symbol(env))
- { Lisp_Object ve = qvalue(env);
- if (is_float(ve)) eps = double_float_val(ve);
- }
- cc = aa + bb;
- ra = cc/aa;
- if (ra < 0.0) ra = -ra;
- if (ra < eps) cc = 0.0;
- }
- else
- { ah &= 0x7fffffff;
- bh &= 0x7fffffff;
- if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
- cc = aa + bb;
- }
- }
- a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
- errexit();
- return onevalue(a);
- }
- /*
- * symbolic procedure safe!-fp!-times(x,y);
- * if zerop x or zerop y then 0.0
- * else if x=1.0 then y else if y=1.0 then x else
- * begin scalar u,v; u := abs x; v := abs y;
- * if u>=1.0 and u<=!!timmax then
- * if v<=!!timmax then go to ret else return nil;
- * if u>!!timmax then if v<=1.0 then go to ret else return nil;
- * if u<1.0 and u>=!!timmin then
- * if v>=!!timmin then go to ret else return nil;
- * if u<!!timmin and v<1.0 then return nil;
- * ret: return times2(x,y) end;
- */
- static Lisp_Object Lsafe_fp_times(Lisp_Object nil,
- Lisp_Object a, Lisp_Object b)
- /*
- * safe!-fp!-times must always be given floating point arguments. In
- * most reasonable cases it just returns the floating point product. If
- * there was some chance that the product might either overflow or underflow
- * then the value NIL is returned instead. REDUCE requires that if this
- * function returns a non-overflow result than two such returned values
- * can be added witjout fear of overflow, as in a*b+c*d. Hence I ought to
- * report trouble slightly earlier than I might otherwise. - but REDUCE is
- * being changed to remove this oddity, and it seems it could only cause
- * trouble in (1.0,max)*(max, 1.0) complex multiplication, so I am not
- * going to worry...
- */
- {
- double aa, bb, cc;
- int32 ah, bh;
- if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-times", a, b);
- /*
- * Multiplication by zero is handled as a special case here - doing so
- * means that I do not have to worry about the special case of zero
- * exponents later on, and it also avoids allocating fresh space to hold
- * a new floating point zero value.
- */
- if ((aa = double_float_val(a)) == 0.0) return onevalue(a);
- if ((bb = double_float_val(b)) == 0.0) return onevalue(b);
- if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
- return aerror("VAX or 370 FP rep");
- ah = top_half(aa);
- bh = top_half(bb);
- /*
- * Here I am going to assume IEEE-format numbers. I hope that I have
- * picked out the word containing the exponent and that it is positioned in
- * the word where I expect.
- */
- ah = (ah >> 20) & 0x7ff;
- bh = (bh >> 20) & 0x7ff;
- ah = ah + bh;
- /*
- * I can estimate the value of the product by adding the exponents of the
- * two operands.
- */
- if (ah < 0x400 || ah >= 0xbfd) return onevalue(nil);
- cc = aa * bb;
- a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
- errexit();
- return onevalue(a);
- }
- /*
- * symbolic procedure safe!-fp!-quot(x,y);
- * if zerop y then rdqoterr()
- * else if zerop x then 0.0 else if y=1.0 then x else
- * begin scalar u,v; u := abs x; v := abs y;
- * if u>=1.0 and u<=!!timmax then
- * if v>=!!timmin then go to ret else return nil;
- * if u>!!timmax then if v>=1.0 then go to ret else return nil;
- * if u<1.0 and u>=!!timmin then
- * if v<=!!timmax then go to ret else return nil;
- * if u<!!timmin and v>1.0 then return nil;
- * ret: return quotient(x,y) end;
- */
- static Lisp_Object Lsafe_fp_quot(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- double aa, bb, cc;
- int32 ah, bh;
- if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-quot", a, b);
- if ((aa = double_float_val(a)) == 0.0) return onevalue(a);
- /*
- * I pass division by zero back to the general case here.
- */
- if ((bb = double_float_val(b)) == 0.0) return onevalue(nil);
- if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
- return aerror("VAX or 370 FP rep");
- ah = top_half(aa);
- bh = top_half(bb);
- ah = (ah >> 20) & 0x7ff;
- bh = (bh >> 20) & 0x7ff;
- ah = ah - bh;
- if (ah <= -0x3fe || ah >= 0x3fe) return onevalue(nil);
- cc = aa / bb;
- a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
- errexit();
- return onevalue(a);
- }
- /*
- * symbolic procedure safe!-fp!-pl(x,y);
- * % floating plus protect from under- and over-flows but no zero
- * % result check.
- * if zerop x then y else if zerop y then x
- * else if x>0 and y>0 then
- * if x<!!plumax and y<!!plumax then plus2(x,y) else nil
- * else if x<0 and y<0 then
- * if (-x<!!plumax and -y<!!plumax) then plus2(x,y) else nil
- * else if abs x<!!plumin or abs y<!!plumin then nil else plus2(x,y);
- */
- static Lisp_Object Lsafe_fp_pl(Lisp_Object nil, Lisp_Object a, Lisp_Object b)
- {
- double aa, bb, cc;
- int32 ah, bh;
- if (!is_float(a) || !is_float(b)) return aerror2("safe-fp-pl", a, b);
- if ((aa = double_float_val(a)) == 0.0) return onevalue(b);
- if ((bb = double_float_val(b)) == 0.0) return onevalue(a);
- if (current_fp_rep & (FP_VAXREP|FP_IBMREP))
- return aerror("VAX or 370 FP rep");
- ah = top_half(aa);
- bh = top_half(bb);
- if (ah >= 0)
- { if (bh >= 0)
- { if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
- }
- else
- { bh &= 0x7fffffff;
- if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
- }
- }
- else
- { if (bh >= 0)
- { ah &= 0x7fffffff;
- if (ah < 0x03500000 && bh < 0x03500000) return onevalue(nil);
- }
- else
- { ah &= 0x7fffffff;
- bh &= 0x7fffffff;
- if (ah >= 0x7fe00000 || bh >= 0x7fe00000) return onevalue(nil);
- }
- }
- cc = aa + bb;
- a = make_boxfloat(cc, TYPE_DOUBLE_FLOAT);
- errexit();
- return onevalue(a);
- }
- /*
- * symbolic procedure safe!-fp!-pl0(x,y);
- * % protects floating plus against under-flow only.
- * if zerop x then y else if zerop y then x
- * else if abs x<!!plumin and abs y<!!plumin then nil else plus2(x,y);
- *
- * implement as safe!-fp!-pl without MUCH loss of speed.
- */
- static Lisp_Object Llose_precision(Lisp_Object nil,
- Lisp_Object a, Lisp_Object n)
- {
- double aa;
- char buffer[64];
- int32 nn;
- if (!is_float(a) || !is_fixnum(n)) return aerror2("lose_precision", a, n);
- nn = int_of_fixnum(n);
- if (nn <= 0 || nn >= 20) return onevalue(a);
- sprintf(buffer, "%.*g", (int)nn, double_float_val(a));
- if (sscanf(buffer, "%lg", &aa) != 1) return aerror("lose-precision");
- a = make_boxfloat(aa, TYPE_DOUBLE_FLOAT);
- errexit();
- return onevalue(a);
- }
- setup_type const arith08_setup[] =
- {
- /*
- * The next few are JUST for REDUCE, but they are expected to speed up
- * rounded-mode arithmetic rather a lot.
- */
- {"lose-precision", too_few_2, Llose_precision, wrong_no_2},
- {"safe-fp-plus", too_few_2, Lsafe_fp_plus, wrong_no_2},
- {"safe-fp-times", too_few_2, Lsafe_fp_times, wrong_no_2},
- {"safe-fp-quot", too_few_2, Lsafe_fp_quot, wrong_no_2},
- {"safe-fp-pl", too_few_2, Lsafe_fp_pl, wrong_no_2},
- {"safe-fp-pl0", too_few_2, Lsafe_fp_pl, wrong_no_2},
- /* End of REDUCE specialities */
- {"ceiling", Lceiling, Lceiling_2, wrong_no_1},
- {"floor", Lfloor, Lfloor_2, wrong_no_1},
- {"round", Lround, Lround_2, wrong_no_1},
- {"truncate", Ltruncate, Ltruncate_2, wrong_no_1},
- #ifdef COMMON
- {"boole", wrong_no_na, wrong_no_nb, Lboole},
- {"byte", too_few_2, Lbyte, wrong_no_2},
- {"byte-position", Lbyte_position, too_many_1, wrong_no_1},
- {"byte-size", Lbyte_size, too_many_1, wrong_no_1},
- {"complex", Lcomplex_1, Lcomplex_2, wrong_no_2},
- {"conjugate", Lconjugate, too_many_1, wrong_no_1},
- {"decode-float", Ldecode_float, too_many_1, wrong_no_1},
- {"float-denormalized-p", Lfloat_denormalized_p, too_many_1, wrong_no_1},
- {"float-infinity-p", Lfloat_infinity_p, too_many_1, wrong_no_1},
- {"denominator", Ldenominator, too_many_1, wrong_no_1},
- {"deposit-field", wrong_no_na, wrong_no_nb, Ldeposit_field},
- {"dpb", wrong_no_na, wrong_no_nb, Ldpb},
- {"ffloor", too_few_2, Lffloor, wrong_no_2},
- {"float-digits", Lfloat_digits, too_many_1, wrong_no_1},
- {"float-precision", Lfloat_precision, too_many_1, wrong_no_1},
- {"float-radix", Lfloat_radix, too_many_1, wrong_no_1},
- {"float-sign", Lfloat_sign1, Lfloat_sign2, wrong_no_2},
- {"fround", too_few_2, Lfround, wrong_no_2},
- {"ftruncate", too_few_2, Lftruncate, wrong_no_2},
- {"gcd", Lgcd_1, Lgcd, Lgcd_n},
- {"imagpart", Limagpart, too_many_1, wrong_no_1},
- {"integer-decode-float", Linteger_decode_float, too_many_1, wrong_no_1},
- {"integer-length", Linteger_length, too_many_1, wrong_no_1},
- {"ldb", too_few_2, Lldb, wrong_no_2},
- {"ldb-test", too_few_2, Lldb_test, wrong_no_2},
- {"lcm", Llcm_1, Llcm, Llcm_n},
- {"logbitp", too_few_2, Llogbitp, wrong_no_2},
- {"logcount", Llogcount, too_many_1, wrong_no_1},
- {"logtest", too_few_2, Llogtest, wrong_no_2},
- {"mask-field", too_few_2, Lmask_field, wrong_no_2},
- {"numerator", Lnumerator, too_many_1, wrong_no_1},
- {"realpart", Lrealpart, too_many_1, wrong_no_1},
- {"scale-float", too_few_2, Lscale_float, wrong_no_2},
- #else
- {"fix", Ltruncate, too_many_1, wrong_no_1},
- {"gcdn", too_few_2, Lgcd, wrong_no_2},
- {"lcmn", too_few_2, Llcm, wrong_no_2},
- #endif
- {NULL, 0,0,0}
- };
- /* end of arith08.c */
|