blob: 67e3cf7796fcbc9f9cc0b1a3d4f604d61a32eda4 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossume5372401993-03-16 12:15:04 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Math module -- standard C math library functions, pi and e */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Guido van Rossum801f4731990-12-20 23:09:14 +000029#include <errno.h>
Guido van Rossum801f4731990-12-20 23:09:14 +000030
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000031#include "modsupport.h"
32
Guido van Rossum234f9421993-06-17 12:35:49 +000033#define getdoublearg(v, a) getargs(v, "d", a)
34#define get2doublearg(v, a, b) getargs(v, "(dd)", a, b)
35
Guido van Rossum3f5da241990-12-20 15:06:42 +000036#include <math.h>
37
Guido van Rossum9575a441993-04-07 14:06:14 +000038#ifdef i860
39/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
40#undef HUGE_VAL
41#endif
42
Guido van Rossum2d709b11992-01-14 18:37:27 +000043#ifndef __STDC__
Guido van Rossumdf840d91992-03-27 17:29:44 +000044extern double fmod PROTO((double, double));
Guido van Rossum2d709b11992-01-14 18:37:27 +000045#endif
46
Guido van Rossum8832b621991-12-16 15:44:24 +000047#ifdef HUGE_VAL
48#define CHECK(x) if (errno != 0) ; \
49 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
50 else errno = ERANGE
51#else
52#define CHECK(x) /* Don't know how to check */
53#endif
54
55static object *
56math_error()
57{
58 if (errno == EDOM)
59 err_setstr(ValueError, "math domain error");
60 else if (errno == ERANGE)
61 err_setstr(OverflowError, "math range error");
62 else
Guido van Rossum444db071992-02-26 15:26:56 +000063 err_errno(ValueError); /* Unexpected math error */
Guido van Rossum8832b621991-12-16 15:44:24 +000064 return NULL;
65}
66
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067static object *
68math_1(args, func)
69 object *args;
70 double (*func) FPROTO((double));
71{
72 double x;
73 if (!getdoublearg(args, &x))
74 return NULL;
75 errno = 0;
76 x = (*func)(x);
Guido van Rossum8832b621991-12-16 15:44:24 +000077 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +000079 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 else
81 return newfloatobject(x);
82}
83
84static object *
85math_2(args, func)
86 object *args;
87 double (*func) FPROTO((double, double));
88{
89 double x, y;
90 if (!get2doublearg(args, &x, &y))
91 return NULL;
92 errno = 0;
93 x = (*func)(x, y);
Guido van Rossum8832b621991-12-16 15:44:24 +000094 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +000096 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 else
98 return newfloatobject(x);
99}
100
101#define FUNC1(stubname, func) \
102 static object * stubname(self, args) object *self, *args; { \
103 return math_1(args, func); \
104 }
105
106#define FUNC2(stubname, func) \
107 static object * stubname(self, args) object *self, *args; { \
108 return math_2(args, func); \
109 }
110
111FUNC1(math_acos, acos)
112FUNC1(math_asin, asin)
113FUNC1(math_atan, atan)
114FUNC2(math_atan2, atan2)
115FUNC1(math_ceil, ceil)
116FUNC1(math_cos, cos)
117FUNC1(math_cosh, cosh)
118FUNC1(math_exp, exp)
119FUNC1(math_fabs, fabs)
120FUNC1(math_floor, floor)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000121FUNC2(math_fmod, fmod)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000122FUNC1(math_log, log)
123FUNC1(math_log10, log10)
Guido van Rossum1492c271991-07-27 21:38:43 +0000124#ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000125FUNC2(math_pow, power)
126#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127FUNC2(math_pow, pow)
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000128#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129FUNC1(math_sin, sin)
130FUNC1(math_sinh, sinh)
131FUNC1(math_sqrt, sqrt)
132FUNC1(math_tan, tan)
133FUNC1(math_tanh, tanh)
134
Guido van Rossum98d54331991-11-12 15:44:14 +0000135double frexp PROTO((double, int *));
136double ldexp PROTO((double, int));
137double modf PROTO((double, double *));
Guido van Rossumd18ad581991-10-24 14:57:21 +0000138
139static object *
140math_frexp(self, args)
141 object *self;
142 object *args;
143{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000144 double x;
145 int i;
146 if (!getdoublearg(args, &x))
147 return NULL;
148 errno = 0;
149 x = frexp(x, &i);
Guido van Rossum8832b621991-12-16 15:44:24 +0000150 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000151 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000152 return math_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000153 return mkvalue("(di)", x, i);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000154}
155
156static object *
157math_ldexp(self, args)
158 object *self;
159 object *args;
160{
161 double x, y;
162 /* Cheat -- allow float as second argument */
163 if (!get2doublearg(args, &x, &y))
164 return NULL;
165 errno = 0;
166 x = ldexp(x, (int)y);
Guido van Rossum8832b621991-12-16 15:44:24 +0000167 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000168 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000169 return math_error();
Guido van Rossumd18ad581991-10-24 14:57:21 +0000170 else
171 return newfloatobject(x);
172}
173
174static object *
175math_modf(self, args)
176 object *self;
177 object *args;
178{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000179 double x, y;
180 if (!getdoublearg(args, &x))
181 return NULL;
182 errno = 0;
183 x = modf(x, &y);
Guido van Rossum8832b621991-12-16 15:44:24 +0000184 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000185 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000186 return math_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000187 return mkvalue("(dd)", x, y);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000188}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189
190static struct methodlist math_methods[] = {
191 {"acos", math_acos},
192 {"asin", math_asin},
193 {"atan", math_atan},
194 {"atan2", math_atan2},
195 {"ceil", math_ceil},
196 {"cos", math_cos},
197 {"cosh", math_cosh},
198 {"exp", math_exp},
199 {"fabs", math_fabs},
200 {"floor", math_floor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201 {"fmod", math_fmod},
Guido van Rossumd18ad581991-10-24 14:57:21 +0000202 {"frexp", math_frexp},
203 {"ldexp", math_ldexp},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 {"log", math_log},
205 {"log10", math_log10},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 {"modf", math_modf},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207 {"pow", math_pow},
208 {"sin", math_sin},
209 {"sinh", math_sinh},
210 {"sqrt", math_sqrt},
211 {"tan", math_tan},
212 {"tanh", math_tanh},
213 {NULL, NULL} /* sentinel */
214};
215
216void
217initmath()
218{
219 object *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000220
221 m = initmodule("math", math_methods);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 d = getmoduledict(m);
Guido van Rossumeb38d241990-11-18 17:36:45 +0000223 dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
224 DECREF(v);
225 dictinsert(d, "e", v = newfloatobject(exp(1.0)));
226 DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227}