Mercurial > emacs
changeset 4506:6131dad14f6f
(Ffloor): Optional second operand specifies divisor, as in Common Lisp.
(syms_of_floatfns): Invoke syms_of_floatfns even if LISP_FLOAT_TYPE
isn't defined, since `(floor A B)' is now needed for integers.
author | Paul Eggert <eggert@twinsun.com> |
---|---|
date | Tue, 10 Aug 1993 04:14:17 +0000 |
parents | 348f6a32d9b5 |
children | e61769cebbd4 |
files | src/floatfns.c |
diffstat | 1 files changed, 61 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/floatfns.c Tue Aug 10 01:32:23 1993 +0000 +++ b/src/floatfns.c Tue Aug 10 04:14:17 1993 +0000 @@ -669,19 +669,66 @@ return arg; } -DEFUN ("floor", Ffloor, Sfloor, 1, 1, 0, - "Return the largest integer no greater than ARG. (Round towards -inf.)") - (arg) - register Lisp_Object arg; +#endif /* LISP_FLOAT_TYPE */ + + +DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0, + "Return the largest integer no greater than ARG. (Round towards -inf.)\n\ +With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR.") + (arg, divisor) + register Lisp_Object arg, divisor; { CHECK_NUMBER_OR_FLOAT (arg, 0); + if (! NILP (divisor)) + { + int i1, i2; + + CHECK_NUMBER_OR_FLOAT (divisor, 1); + +#ifdef LISP_FLOAT_TYPE + if (XTYPE (arg) == Lisp_Float || XTYPE (divisor) == Lisp_Float) + { + double f1, f2; + + f1 = XTYPE (arg) == Lisp_Float ? XFLOAT (arg)->data : XINT (arg); + f2 = (XTYPE (divisor) == Lisp_Float + ? XFLOAT (divisor)->data : XINT (divisor)); + if (f2 == 0) + Fsignal (Qarith_error, Qnil); + + IN_FLOAT2 (XSET (arg, Lisp_Int, floor (f1 / f2)), + "floor", arg, divisor); + return arg; + } +#endif + + i1 = XINT (arg); + i2 = XINT (divisor); + + if (i2 == 0) + Fsignal (Qarith_error, Qnil); + + /* With C's /, the result is implementation-defined if either operand + is negative, so use only nonnegative operands. */ + i1 = (i2 < 0 + ? (i1 <= 0 ? -i1 / -i2 : -1 - ((i1 - 1) / -i2)) + : (i1 < 0 ? -1 - ((-1 - i1) / i2) : i1 / i2)); + + XSET (arg, Lisp_Int, i1); + return arg; + } + +#ifdef LISP_FLOAT_TYPE if (XTYPE (arg) == Lisp_Float) IN_FLOAT (XSET (arg, Lisp_Int, floor (XFLOAT (arg)->data)), "floor", arg); +#endif return arg; } +#ifdef LISP_FLOAT_TYPE + DEFUN ("round", Fround, Sround, 1, 1, 0, "Return the nearest integer to ARG.") (arg) @@ -827,8 +874,16 @@ in_float = 0; } +#else /* not LISP_FLOAT_TYPE */ + +init_floatfns () +{} + +#endif /* not LISP_FLOAT_TYPE */ + syms_of_floatfns () { +#ifdef LISP_FLOAT_TYPE defsubr (&Sacos); defsubr (&Sasin); defsubr (&Satan); @@ -867,17 +922,8 @@ defsubr (&Sfloat); defsubr (&Slogb); defsubr (&Sceiling); - defsubr (&Sfloor); defsubr (&Sround); defsubr (&Struncate); +#endif /* LISP_FLOAT_TYPE */ + defsubr (&Sfloor); } - -#else /* not LISP_FLOAT_TYPE */ - -init_floatfns () -{} - -syms_of_floatfns () -{} - -#endif /* not LISP_FLOAT_TYPE */