aboutsummaryrefslogtreecommitdiffstats
path: root/src/floatfns.c
diff options
context:
space:
mode:
authorPaul Eggert1993-08-10 04:14:17 +0000
committerPaul Eggert1993-08-10 04:14:17 +0000
commitfc2157cb0f852c92ad5515a1f918326c6731b53c (patch)
tree7ad1cdd185430d97184c79e6ee27509349855b48 /src/floatfns.c
parentd7cb42c3490e1cb58a5b4ccbfda2368115a7af58 (diff)
downloademacs-fc2157cb0f852c92ad5515a1f918326c6731b53c.tar.gz
emacs-fc2157cb0f852c92ad5515a1f918326c6731b53c.zip
(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.
Diffstat (limited to 'src/floatfns.c')
-rw-r--r--src/floatfns.c76
1 files changed, 61 insertions, 15 deletions
diff --git a/src/floatfns.c b/src/floatfns.c
index 8f0515a84b5..6b0f68585cd 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -669,19 +669,66 @@ DEFUN ("ceiling", Fceiling, Sceiling, 1, 1, 0,
669 return arg; 669 return arg;
670} 670}
671 671
672DEFUN ("floor", Ffloor, Sfloor, 1, 1, 0, 672#endif /* LISP_FLOAT_TYPE */
673 "Return the largest integer no greater than ARG. (Round towards -inf.)") 673
674 (arg) 674
675 register Lisp_Object arg; 675DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
676 "Return the largest integer no greater than ARG. (Round towards -inf.)\n\
677With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR.")
678 (arg, divisor)
679 register Lisp_Object arg, divisor;
676{ 680{
677 CHECK_NUMBER_OR_FLOAT (arg, 0); 681 CHECK_NUMBER_OR_FLOAT (arg, 0);
678 682
683 if (! NILP (divisor))
684 {
685 int i1, i2;
686
687 CHECK_NUMBER_OR_FLOAT (divisor, 1);
688
689#ifdef LISP_FLOAT_TYPE
690 if (XTYPE (arg) == Lisp_Float || XTYPE (divisor) == Lisp_Float)
691 {
692 double f1, f2;
693
694 f1 = XTYPE (arg) == Lisp_Float ? XFLOAT (arg)->data : XINT (arg);
695 f2 = (XTYPE (divisor) == Lisp_Float
696 ? XFLOAT (divisor)->data : XINT (divisor));
697 if (f2 == 0)
698 Fsignal (Qarith_error, Qnil);
699
700 IN_FLOAT2 (XSET (arg, Lisp_Int, floor (f1 / f2)),
701 "floor", arg, divisor);
702 return arg;
703 }
704#endif
705
706 i1 = XINT (arg);
707 i2 = XINT (divisor);
708
709 if (i2 == 0)
710 Fsignal (Qarith_error, Qnil);
711
712 /* With C's /, the result is implementation-defined if either operand
713 is negative, so use only nonnegative operands. */
714 i1 = (i2 < 0
715 ? (i1 <= 0 ? -i1 / -i2 : -1 - ((i1 - 1) / -i2))
716 : (i1 < 0 ? -1 - ((-1 - i1) / i2) : i1 / i2));
717
718 XSET (arg, Lisp_Int, i1);
719 return arg;
720 }
721
722#ifdef LISP_FLOAT_TYPE
679 if (XTYPE (arg) == Lisp_Float) 723 if (XTYPE (arg) == Lisp_Float)
680 IN_FLOAT (XSET (arg, Lisp_Int, floor (XFLOAT (arg)->data)), "floor", arg); 724 IN_FLOAT (XSET (arg, Lisp_Int, floor (XFLOAT (arg)->data)), "floor", arg);
725#endif
681 726
682 return arg; 727 return arg;
683} 728}
684 729
730#ifdef LISP_FLOAT_TYPE
731
685DEFUN ("round", Fround, Sround, 1, 1, 0, 732DEFUN ("round", Fround, Sround, 1, 1, 0,
686 "Return the nearest integer to ARG.") 733 "Return the nearest integer to ARG.")
687 (arg) 734 (arg)
@@ -827,8 +874,16 @@ init_floatfns ()
827 in_float = 0; 874 in_float = 0;
828} 875}
829 876
877#else /* not LISP_FLOAT_TYPE */
878
879init_floatfns ()
880{}
881
882#endif /* not LISP_FLOAT_TYPE */
883
830syms_of_floatfns () 884syms_of_floatfns ()
831{ 885{
886#ifdef LISP_FLOAT_TYPE
832 defsubr (&Sacos); 887 defsubr (&Sacos);
833 defsubr (&Sasin); 888 defsubr (&Sasin);
834 defsubr (&Satan); 889 defsubr (&Satan);
@@ -867,17 +922,8 @@ syms_of_floatfns ()
867 defsubr (&Sfloat); 922 defsubr (&Sfloat);
868 defsubr (&Slogb); 923 defsubr (&Slogb);
869 defsubr (&Sceiling); 924 defsubr (&Sceiling);
870 defsubr (&Sfloor);
871 defsubr (&Sround); 925 defsubr (&Sround);
872 defsubr (&Struncate); 926 defsubr (&Struncate);
927#endif /* LISP_FLOAT_TYPE */
928 defsubr (&Sfloor);
873} 929}
874
875#else /* not LISP_FLOAT_TYPE */
876
877init_floatfns ()
878{}
879
880syms_of_floatfns ()
881{}
882
883#endif /* not LISP_FLOAT_TYPE */