comparison src/floatfns.c @ 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 800c035273e9
children 9e627ca8f0a0
comparison
equal deleted inserted replaced
6374:71e61b314fe9 6375:212dcd2c06e4
178 #else 178 #else
179 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0) 179 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
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
194 double 217 double
195 extract_float (num) 218 extract_float (num)
701 register Lisp_Object arg; 724 register Lisp_Object arg;
702 { 725 {
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 }
710 738
711 #endif /* LISP_FLOAT_TYPE */ 739 #endif /* LISP_FLOAT_TYPE */
734 f2 = (XTYPE (divisor) == Lisp_Float 762 f2 = (XTYPE (divisor) == Lisp_Float
735 ? XFLOAT (divisor)->data : XINT (divisor)); 763 ? XFLOAT (divisor)->data : XINT (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
744 772
745 i1 = XINT (arg); 773 i1 = XINT (arg);
758 return arg; 786 return arg;
759 } 787 }
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;
767 } 799 }
768 800
774 register Lisp_Object arg; 806 register Lisp_Object arg;
775 { 807 {
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 }
784 821
785 DEFUN ("truncate", Ftruncate, Struncate, 1, 1, 0, 822 DEFUN ("truncate", Ftruncate, Struncate, 1, 1, 0,
789 register Lisp_Object arg; 826 register Lisp_Object arg;
790 { 827 {
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 }
798 840
799 /* It's not clear these are worth adding. */ 841 /* It's not clear these are worth adding. */