comparison src/floatfns.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents a86b2b5e0111
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
53 53
54 /* Need to define a differentiating symbol -- see sysfloat.h */ 54 /* Need to define a differentiating symbol -- see sysfloat.h */
55 #define THIS_FILENAME floatfns 55 #define THIS_FILENAME floatfns
56 #include "sysfloat.h" 56 #include "sysfloat.h"
57 57
58 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT 58 #ifndef HAVE_RINT
59 if `rint' exists but does not work right. */
60 #ifdef HAVE_RINT
61 #define emacs_rint rint
62 #else
63 static double 59 static double
64 emacs_rint (double x) 60 rint (double x)
65 { 61 {
66 double r = floor (x + 0.5); 62 double r = floor (x + 0.5);
67 double diff = fabs (r - x); 63 double diff = fabs (r - x);
68 /* Round to even and correct for any roundoff errors. */ 64 /* Round to even and correct for any roundoff errors. */
69 if (diff >= 0.5 && (diff > 0.5 || r != 2.0 * floor (r / 2.0))) 65 if (diff >= 0.5 && (diff > 0.5 || r != 2.0 * floor (r / 2.0)))
77 static int in_float; 73 static int in_float;
78 74
79 /* If an argument is out of range for a mathematical function, 75 /* If an argument is out of range for a mathematical function,
80 here is the actual argument value to use in the error message. */ 76 here is the actual argument value to use in the error message. */
81 static Lisp_Object float_error_arg, float_error_arg2; 77 static Lisp_Object float_error_arg, float_error_arg2;
82 static const char *float_error_fn_name; 78 static CONST char *float_error_fn_name;
83 79
84 /* Evaluate the floating point expression D, recording NUM 80 /* Evaluate the floating point expression D, recording NUM
85 as the original argument for error messages. 81 as the original argument for error messages.
86 D is normally an assignment expression. 82 D is normally an assignment expression.
87 Handle errors which may result in signals or may set errno. 83 Handle errors which may result in signals or may set errno.
110 #define IN_FLOAT2(d, name, num, num2) (in_float = 2, (d), in_float = 0) 106 #define IN_FLOAT2(d, name, num, num2) (in_float = 2, (d), in_float = 0)
111 #endif 107 #endif
112 108
113 109
114 #define arith_error(op,arg) \ 110 #define arith_error(op,arg) \
115 Fsignal (Qarith_error, list2 (build_string (op), arg)) 111 Fsignal (Qarith_error, list2 (build_string ((op)), (arg)))
116 #define range_error(op,arg) \ 112 #define range_error(op,arg) \
117 Fsignal (Qrange_error, list2 (build_string (op), arg)) 113 Fsignal (Qrange_error, list2 (build_string ((op)), (arg)))
118 #define range_error2(op,a1,a2) \ 114 #define range_error2(op,a1,a2) \
119 Fsignal (Qrange_error, list3 (build_string (op), a1, a2)) 115 Fsignal (Qrange_error, list3 (build_string ((op)), (a1), (a2)))
120 #define domain_error(op,arg) \ 116 #define domain_error(op,arg) \
121 Fsignal (Qdomain_error, list2 (build_string (op), arg)) 117 Fsignal (Qdomain_error, list2 (build_string ((op)), (arg)))
122 #define domain_error2(op,a1,a2) \ 118 #define domain_error2(op,a1,a2) \
123 Fsignal (Qdomain_error, list3 (build_string (op), a1, a2)) 119 Fsignal (Qdomain_error, list3 (build_string ((op)), (a1), (a2)))
124 120
125 121
126 /* Convert float to Lisp Integer if it fits, else signal a range 122 /* Convert float to Lisp Integer if it fits, else signal a range
127 error using the given arguments. */ 123 error using the given arguments. */
128 static Lisp_Object 124 static Lisp_Object
129 float_to_int (double x, const char *name, Lisp_Object num, Lisp_Object num2) 125 float_to_int (double x, CONST char *name, Lisp_Object num, Lisp_Object num2)
130 { 126 {
131 if (x >= ((EMACS_INT) 1 << (VALBITS-1)) 127 if (x >= ((EMACS_INT) 1 << (VALBITS-1))
132 || x <= - ((EMACS_INT) 1 << (VALBITS-1)) - (EMACS_INT) 1) 128 || x <= - ((EMACS_INT) 1 << (VALBITS-1)) - (EMACS_INT) 1)
133 { 129 {
134 if (!UNBOUNDP (num2)) 130 if (!UNBOUNDP (num2))
162 } 158 }
163 } 159 }
164 160
165 161
166 static Lisp_Object 162 static Lisp_Object
167 mark_float (Lisp_Object obj) 163 mark_float (Lisp_Object obj, void (*markobj) (Lisp_Object))
168 { 164 {
169 return Qnil; 165 return Qnil;
170 } 166 }
171 167
172 static int 168 static int
181 /* mod the value down to 32-bit range */ 177 /* mod the value down to 32-bit range */
182 /* #### change for 64-bit machines */ 178 /* #### change for 64-bit machines */
183 return (unsigned long) fmod (extract_float (obj), 4e9); 179 return (unsigned long) fmod (extract_float (obj), 4e9);
184 } 180 }
185 181
186 static const struct lrecord_description float_description[] = {
187 { XD_END }
188 };
189
190 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("float", float, 182 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("float", float,
191 mark_float, print_float, 0, float_equal, 183 mark_float, print_float, 0, float_equal,
192 float_hash, float_description, 184 float_hash, struct Lisp_Float);
193 Lisp_Float);
194 185
195 /* Extract a Lisp number as a `double', or signal an error. */ 186 /* Extract a Lisp number as a `double', or signal an error. */
196 187
197 double 188 double
198 extract_float (Lisp_Object num) 189 extract_float (Lisp_Object num)
703 (arg)) 694 (arg))
704 { 695 {
705 double f = extract_float (arg); 696 double f = extract_float (arg);
706 697
707 if (f == 0.0) 698 if (f == 0.0)
708 return make_int (- (EMACS_INT)(((EMACS_UINT) 1) << (VALBITS - 1))); /* most-negative-fixnum */ 699 return make_int (- (int)((((EMACS_UINT) 1) << (VALBITS - 1)))); /* most-negative-fixnum */
709 #ifdef HAVE_LOGB 700 #ifdef HAVE_LOGB
710 { 701 {
711 Lisp_Object val; 702 Lisp_Object val;
712 IN_FLOAT (val = make_int ((EMACS_INT) logb (f)), "logb", arg); 703 IN_FLOAT (val = make_int ((int) logb (f)), "logb", arg);
713 return val; 704 return (val);
714 } 705 }
715 #else 706 #else
716 #ifdef HAVE_FREXP 707 #ifdef HAVE_FREXP
717 { 708 {
718 int exqp; 709 int exqp;
719 IN_FLOAT (frexp (f, &exqp), "logb", arg); 710 IN_FLOAT (frexp (f, &exqp), "logb", arg);
720 return make_int (exqp - 1); 711 return (make_int (exqp - 1));
721 } 712 }
722 #else 713 #else
723 { 714 {
724 int i; 715 int i;
725 double d; 716 double d;
739 for (i = 1, d = 2.0; d * d <= f; i += i) 730 for (i = 1, d = 2.0; d * d <= f; i += i)
740 d *= d; 731 d *= d;
741 f /= d; 732 f /= d;
742 val += i; 733 val += i;
743 } 734 }
744 return make_int (val); 735 return (make_int (val));
745 } 736 }
746 #endif /* ! HAVE_FREXP */ 737 #endif /* ! HAVE_FREXP */
747 #endif /* ! HAVE_LOGB */ 738 #endif /* ! HAVE_LOGB */
748 } 739 }
749 #endif /* LISP_FLOAT_TYPE */ 740 #endif /* LISP_FLOAT_TYPE */
833 #ifdef LISP_FLOAT_TYPE 824 #ifdef LISP_FLOAT_TYPE
834 if (FLOATP (arg)) 825 if (FLOATP (arg))
835 { 826 {
836 double d; 827 double d;
837 /* Screw the prevailing rounding mode. */ 828 /* Screw the prevailing rounding mode. */
838 IN_FLOAT ((d = emacs_rint (XFLOAT_DATA (arg))), "round", arg); 829 IN_FLOAT ((d = rint (XFLOAT_DATA (arg))), "round", arg);
839 return (float_to_int (d, "round", arg, Qunbound)); 830 return (float_to_int (d, "round", arg, Qunbound));
840 } 831 }
841 #endif /* LISP_FLOAT_TYPE */ 832 #endif /* LISP_FLOAT_TYPE */
842 833
843 if (INTP (arg)) 834 if (INTP (arg))
893 Return the nearest integer to ARG, as a float. 884 Return the nearest integer to ARG, as a float.
894 */ 885 */
895 (arg)) 886 (arg))
896 { 887 {
897 double d = extract_float (arg); 888 double d = extract_float (arg);
898 IN_FLOAT (d = emacs_rint (d), "fround", arg); 889 IN_FLOAT (d = rint (d), "fround", arg);
899 return make_float (d); 890 return make_float (d);
900 } 891 }
901 892
902 DEFUN ("ftruncate", Fftruncate, 1, 1, 0, /* 893 DEFUN ("ftruncate", Fftruncate, 1, 1, 0, /*
903 Truncate a floating point number to an integral float value. 894 Truncate a floating point number to an integral float value.
986 } 977 }
987 978
988 void 979 void
989 syms_of_floatfns (void) 980 syms_of_floatfns (void)
990 { 981 {
991 INIT_LRECORD_IMPLEMENTATION (float);
992 982
993 /* Trig functions. */ 983 /* Trig functions. */
994 984
995 #ifdef LISP_FLOAT_TYPE 985 #ifdef LISP_FLOAT_TYPE
996 DEFSUBR (Facos); 986 DEFSUBR (Facos);