changeset 6375:212dcd2c06e4

(FLOAT_TO_INT, FLOAT_TO_INT2, range_error2): New macros. (ceiling, floor, round, truncate): Use them.
author Karl Heuer <kwzh@gnu.org>
date Wed, 16 Mar 1994 06:14:56 +0000
parents 71e61b314fe9
children 3fe339cf2dde
files src/floatfns.c
diffstat 1 files changed, 50 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/floatfns.c	Wed Mar 16 05:25:03 1994 +0000
+++ b/src/floatfns.c	Wed Mar 16 06:14:56 1994 +0000
@@ -180,14 +180,37 @@
 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
 #endif
 
+/* Convert float to Lisp_Int if it fits, else signal a range error
+   using the given arguments.  */
+#define FLOAT_TO_INT(x, i, name, num)					\
+  do									\
+    {									\
+      if ((x) >= (1 << (VALBITS-1)) || (x) <= - (1 << (VALBITS-1)) - 1)	\
+	range_error (name, num);					\
+      XSET (i, Lisp_Int,  (int)(x));					\
+    }									\
+  while (0)
+#define FLOAT_TO_INT2(x, i, name, num1, num2)				\
+  do									\
+    {									\
+      if ((x) >= (1 << (VALBITS-1)) || (x) <= - (1 << (VALBITS-1)) - 1)	\
+	range_error2 (name, num1, num2);				\
+      XSET (i, Lisp_Int,  (int)(x));					\
+    }									\
+  while (0)
+
 #define arith_error(op,arg) \
   Fsignal (Qarith_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
 #define range_error(op,arg) \
   Fsignal (Qrange_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
+#define range_error2(op,a1,a2) \
+  Fsignal (Qrange_error, Fcons (build_string ((op)), \
+				Fcons ((a1), Fcons ((a2), Qnil))))
 #define domain_error(op,arg) \
   Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
 #define domain_error2(op,a1,a2) \
-  Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((a1), Fcons ((a2), Qnil))))
+  Fsignal (Qdomain_error, Fcons (build_string ((op)), \
+				 Fcons ((a1), Fcons ((a2), Qnil))))
 
 /* Extract a Lisp number as a `double', or signal an error.  */
 
@@ -703,7 +726,12 @@
   CHECK_NUMBER_OR_FLOAT (arg, 0);
 
   if (XTYPE (arg) == Lisp_Float)
-    IN_FLOAT (XSET (arg, Lisp_Int, ceil (XFLOAT (arg)->data)), "ceiling", arg);
+    {
+      double d;
+
+      IN_FLOAT (d = ceil (XFLOAT (arg)->data), "ceiling", arg);
+      FLOAT_TO_INT (d, arg, "ceiling", arg);
+    }
 
   return arg;
 }
@@ -736,8 +764,8 @@
 	  if (f2 == 0)
 	    Fsignal (Qarith_error, Qnil);
 
-	  IN_FLOAT2 (XSET (arg, Lisp_Int, floor (f1 / f2)),
-		     "floor", arg, divisor);
+	  IN_FLOAT2 (f1 = floor (f1 / f2), "floor", arg, divisor);
+	  FLOAT_TO_INT2 (f1, arg, "floor", arg, divisor);
 	  return arg;
 	}
 #endif
@@ -760,7 +788,11 @@
 
 #ifdef LISP_FLOAT_TYPE
   if (XTYPE (arg) == Lisp_Float)
-    IN_FLOAT (XSET (arg, Lisp_Int, floor (XFLOAT (arg)->data)), "floor", arg);
+    {
+      double d;
+      IN_FLOAT (d = floor (XFLOAT (arg)->data), "floor", arg);
+      FLOAT_TO_INT (d, arg, "floor", arg);
+    }
 #endif
 
   return arg;
@@ -776,8 +808,13 @@
   CHECK_NUMBER_OR_FLOAT (arg, 0);
 
   if (XTYPE (arg) == Lisp_Float)
-    /* Screw the prevailing rounding mode.  */
-    IN_FLOAT (XSET (arg, Lisp_Int, rint (XFLOAT (arg)->data)), "round", arg);
+    {
+      double d;
+
+      /* Screw the prevailing rounding mode.  */
+      IN_FLOAT (d = rint (XFLOAT (arg)->data), "round", arg);
+      FLOAT_TO_INT (d, arg, "round", arg);
+    }
 
   return arg;
 }
@@ -791,7 +828,12 @@
   CHECK_NUMBER_OR_FLOAT (arg, 0);
 
   if (XTYPE (arg) == Lisp_Float)
-    XSET (arg, Lisp_Int, (int) XFLOAT (arg)->data);
+    {
+      double d;
+
+      d = XFLOAT (arg)->data;
+      FLOAT_TO_INT (d, arg, "truncate", arg);
+    }
 
   return arg;
 }