aboutsummaryrefslogtreecommitdiffstats
path: root/src/floatfns.c
diff options
context:
space:
mode:
authorKarl Heuer1994-03-16 06:14:56 +0000
committerKarl Heuer1994-03-16 06:14:56 +0000
commit81a63ccc739d542b689f12177d9de9dae0f0e480 (patch)
tree88c1881dffd464b2dd865d217e961289a2ca9202 /src/floatfns.c
parent4672ee8f4cdf15d366b410c0c7205ad8cd2619e6 (diff)
downloademacs-81a63ccc739d542b689f12177d9de9dae0f0e480.tar.gz
emacs-81a63ccc739d542b689f12177d9de9dae0f0e480.zip
(FLOAT_TO_INT, FLOAT_TO_INT2, range_error2): New macros.
(ceiling, floor, round, truncate): Use them.
Diffstat (limited to 'src/floatfns.c')
-rw-r--r--src/floatfns.c58
1 files changed, 50 insertions, 8 deletions
diff --git a/src/floatfns.c b/src/floatfns.c
index 81a42603b6a..145cae04741 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -180,14 +180,37 @@ static char *float_error_fn_name;
180#define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0) 180#define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
181#endif 181#endif
182 182
183/* Convert float to Lisp_Int if it fits, else signal a range error
184 using the given arguments. */
185#define FLOAT_TO_INT(x, i, name, num) \
186 do \
187 { \
188 if ((x) >= (1 << (VALBITS-1)) || (x) <= - (1 << (VALBITS-1)) - 1) \
189 range_error (name, num); \
190 XSET (i, Lisp_Int, (int)(x)); \
191 } \
192 while (0)
193#define FLOAT_TO_INT2(x, i, name, num1, num2) \
194 do \
195 { \
196 if ((x) >= (1 << (VALBITS-1)) || (x) <= - (1 << (VALBITS-1)) - 1) \
197 range_error2 (name, num1, num2); \
198 XSET (i, Lisp_Int, (int)(x)); \
199 } \
200 while (0)
201
183#define arith_error(op,arg) \ 202#define arith_error(op,arg) \
184 Fsignal (Qarith_error, Fcons (build_string ((op)), Fcons ((arg), Qnil))) 203 Fsignal (Qarith_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
185#define range_error(op,arg) \ 204#define range_error(op,arg) \
186 Fsignal (Qrange_error, Fcons (build_string ((op)), Fcons ((arg), Qnil))) 205 Fsignal (Qrange_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
206#define range_error2(op,a1,a2) \
207 Fsignal (Qrange_error, Fcons (build_string ((op)), \
208 Fcons ((a1), Fcons ((a2), Qnil))))
187#define domain_error(op,arg) \ 209#define domain_error(op,arg) \
188 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((arg), Qnil))) 210 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
189#define domain_error2(op,a1,a2) \ 211#define domain_error2(op,a1,a2) \
190 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((a1), Fcons ((a2), Qnil)))) 212 Fsignal (Qdomain_error, Fcons (build_string ((op)), \
213 Fcons ((a1), Fcons ((a2), Qnil))))
191 214
192/* Extract a Lisp number as a `double', or signal an error. */ 215/* Extract a Lisp number as a `double', or signal an error. */
193 216
@@ -703,7 +726,12 @@ DEFUN ("ceiling", Fceiling, Sceiling, 1, 1, 0,
703 CHECK_NUMBER_OR_FLOAT (arg, 0); 726 CHECK_NUMBER_OR_FLOAT (arg, 0);
704 727
705 if (XTYPE (arg) == Lisp_Float) 728 if (XTYPE (arg) == Lisp_Float)
706 IN_FLOAT (XSET (arg, Lisp_Int, ceil (XFLOAT (arg)->data)), "ceiling", arg); 729 {
730 double d;
731
732 IN_FLOAT (d = ceil (XFLOAT (arg)->data), "ceiling", arg);
733 FLOAT_TO_INT (d, arg, "ceiling", arg);
734 }
707 735
708 return arg; 736 return arg;
709} 737}
@@ -736,8 +764,8 @@ With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR.")
736 if (f2 == 0) 764 if (f2 == 0)
737 Fsignal (Qarith_error, Qnil); 765 Fsignal (Qarith_error, Qnil);
738 766
739 IN_FLOAT2 (XSET (arg, Lisp_Int, floor (f1 / f2)), 767 IN_FLOAT2 (f1 = floor (f1 / f2), "floor", arg, divisor);
740 "floor", arg, divisor); 768 FLOAT_TO_INT2 (f1, arg, "floor", arg, divisor);
741 return arg; 769 return arg;
742 } 770 }
743#endif 771#endif
@@ -760,7 +788,11 @@ With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR.")
760 788
761#ifdef LISP_FLOAT_TYPE 789#ifdef LISP_FLOAT_TYPE
762 if (XTYPE (arg) == Lisp_Float) 790 if (XTYPE (arg) == Lisp_Float)
763 IN_FLOAT (XSET (arg, Lisp_Int, floor (XFLOAT (arg)->data)), "floor", arg); 791 {
792 double d;
793 IN_FLOAT (d = floor (XFLOAT (arg)->data), "floor", arg);
794 FLOAT_TO_INT (d, arg, "floor", arg);
795 }
764#endif 796#endif
765 797
766 return arg; 798 return arg;
@@ -776,8 +808,13 @@ DEFUN ("round", Fround, Sround, 1, 1, 0,
776 CHECK_NUMBER_OR_FLOAT (arg, 0); 808 CHECK_NUMBER_OR_FLOAT (arg, 0);
777 809
778 if (XTYPE (arg) == Lisp_Float) 810 if (XTYPE (arg) == Lisp_Float)
779 /* Screw the prevailing rounding mode. */ 811 {
780 IN_FLOAT (XSET (arg, Lisp_Int, rint (XFLOAT (arg)->data)), "round", arg); 812 double d;
813
814 /* Screw the prevailing rounding mode. */
815 IN_FLOAT (d = rint (XFLOAT (arg)->data), "round", arg);
816 FLOAT_TO_INT (d, arg, "round", arg);
817 }
781 818
782 return arg; 819 return arg;
783} 820}
@@ -791,7 +828,12 @@ Rounds the value toward zero.")
791 CHECK_NUMBER_OR_FLOAT (arg, 0); 828 CHECK_NUMBER_OR_FLOAT (arg, 0);
792 829
793 if (XTYPE (arg) == Lisp_Float) 830 if (XTYPE (arg) == Lisp_Float)
794 XSET (arg, Lisp_Int, (int) XFLOAT (arg)->data); 831 {
832 double d;
833
834 d = XFLOAT (arg)->data;
835 FLOAT_TO_INT (d, arg, "truncate", arg);
836 }
795 837
796 return arg; 838 return arg;
797} 839}