blob: ec315a0cd1257af6c29ee814c79eb904c5962809 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Math module -- standard C math library functions, pi and e */
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000035
Guido van Rossum801f4731990-12-20 23:09:14 +000036#include <errno.h>
Guido van Rossum801f4731990-12-20 23:09:14 +000037
Guido van Rossum234f9421993-06-17 12:35:49 +000038#define getdoublearg(v, a) getargs(v, "d", a)
39#define get2doublearg(v, a, b) getargs(v, "(dd)", a, b)
40
Guido van Rossum6964f731995-03-01 10:34:29 +000041#include "mymath.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000042
Guido van Rossum7081cf51996-05-23 22:56:19 +000043#ifndef _MSC_VER
Guido van Rossumb9418681995-01-12 11:28:16 +000044#ifndef __STDC__
45extern double fmod PROTO((double, double));
46extern double frexp PROTO((double, int *));
47extern double ldexp PROTO((double, int));
48extern double modf PROTO((double, double *));
Guido van Rossum7081cf51996-05-23 22:56:19 +000049#endif /* __STDC__ */
50#endif /* _MSC_VER */
51
Guido van Rossumb9418681995-01-12 11:28:16 +000052
Guido van Rossum9575a441993-04-07 14:06:14 +000053#ifdef i860
54/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
55#undef HUGE_VAL
56#endif
57
Guido van Rossum8832b621991-12-16 15:44:24 +000058#ifdef HUGE_VAL
59#define CHECK(x) if (errno != 0) ; \
60 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
61 else errno = ERANGE
62#else
63#define CHECK(x) /* Don't know how to check */
64#endif
65
66static object *
67math_error()
68{
69 if (errno == EDOM)
70 err_setstr(ValueError, "math domain error");
71 else if (errno == ERANGE)
72 err_setstr(OverflowError, "math range error");
73 else
Guido van Rossum444db071992-02-26 15:26:56 +000074 err_errno(ValueError); /* Unexpected math error */
Guido van Rossum8832b621991-12-16 15:44:24 +000075 return NULL;
76}
77
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078static object *
79math_1(args, func)
80 object *args;
81 double (*func) FPROTO((double));
82{
83 double x;
84 if (!getdoublearg(args, &x))
85 return NULL;
86 errno = 0;
87 x = (*func)(x);
Guido van Rossum8832b621991-12-16 15:44:24 +000088 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +000090 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 else
92 return newfloatobject(x);
93}
94
95static object *
96math_2(args, func)
97 object *args;
98 double (*func) FPROTO((double, double));
99{
100 double x, y;
101 if (!get2doublearg(args, &x, &y))
102 return NULL;
103 errno = 0;
104 x = (*func)(x, y);
Guido van Rossum8832b621991-12-16 15:44:24 +0000105 CHECK(x);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000107 return math_error();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000108 else
109 return newfloatobject(x);
110}
111
112#define FUNC1(stubname, func) \
113 static object * stubname(self, args) object *self, *args; { \
114 return math_1(args, func); \
115 }
116
117#define FUNC2(stubname, func) \
118 static object * stubname(self, args) object *self, *args; { \
119 return math_2(args, func); \
120 }
121
122FUNC1(math_acos, acos)
123FUNC1(math_asin, asin)
124FUNC1(math_atan, atan)
125FUNC2(math_atan2, atan2)
126FUNC1(math_ceil, ceil)
127FUNC1(math_cos, cos)
128FUNC1(math_cosh, cosh)
129FUNC1(math_exp, exp)
Guido van Rossum6412b1d1996-08-08 19:10:21 +0000130#ifdef __MWERKS__
131double myfabs(double x) { return fabs(x); }
132FUNC1(math_fabs, myfabs)
133#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134FUNC1(math_fabs, fabs)
Guido van Rossum6412b1d1996-08-08 19:10:21 +0000135#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136FUNC1(math_floor, floor)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137FUNC2(math_fmod, fmod)
Guido van Rossum411a8bd1994-10-20 22:00:28 +0000138FUNC2(math_hypot, hypot)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139FUNC1(math_log, log)
140FUNC1(math_log10, log10)
Guido van Rossum1492c271991-07-27 21:38:43 +0000141#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 +0000142FUNC2(math_pow, power)
143#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144FUNC2(math_pow, pow)
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000145#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146FUNC1(math_sin, sin)
147FUNC1(math_sinh, sinh)
148FUNC1(math_sqrt, sqrt)
149FUNC1(math_tan, tan)
150FUNC1(math_tanh, tanh)
151
Guido van Rossumb6775db1994-08-01 11:34:53 +0000152
Guido van Rossumd18ad581991-10-24 14:57:21 +0000153static object *
154math_frexp(self, args)
155 object *self;
156 object *args;
157{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000158 double x;
159 int i;
160 if (!getdoublearg(args, &x))
161 return NULL;
162 errno = 0;
163 x = frexp(x, &i);
Guido van Rossum8832b621991-12-16 15:44:24 +0000164 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000165 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000166 return math_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000167 return mkvalue("(di)", x, i);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000168}
169
170static object *
171math_ldexp(self, args)
172 object *self;
173 object *args;
174{
175 double x, y;
176 /* Cheat -- allow float as second argument */
177 if (!get2doublearg(args, &x, &y))
178 return NULL;
179 errno = 0;
180 x = ldexp(x, (int)y);
Guido van Rossum8832b621991-12-16 15:44:24 +0000181 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000182 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000183 return math_error();
Guido van Rossumd18ad581991-10-24 14:57:21 +0000184 else
185 return newfloatobject(x);
186}
187
188static object *
189math_modf(self, args)
190 object *self;
191 object *args;
192{
Guido van Rossumd18ad581991-10-24 14:57:21 +0000193 double x, y;
194 if (!getdoublearg(args, &x))
195 return NULL;
196 errno = 0;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
198{
199 extended e;
200 x = modf(x, &e);
201 y = e;
202}
203#else
Guido van Rossumd18ad581991-10-24 14:57:21 +0000204 x = modf(x, &y);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#endif
Guido van Rossum8832b621991-12-16 15:44:24 +0000206 CHECK(x);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000207 if (errno != 0)
Guido van Rossum8832b621991-12-16 15:44:24 +0000208 return math_error();
Guido van Rossume5372401993-03-16 12:15:04 +0000209 return mkvalue("(dd)", x, y);
Guido van Rossumd18ad581991-10-24 14:57:21 +0000210}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
212static struct methodlist math_methods[] = {
213 {"acos", math_acos},
214 {"asin", math_asin},
215 {"atan", math_atan},
216 {"atan2", math_atan2},
217 {"ceil", math_ceil},
218 {"cos", math_cos},
219 {"cosh", math_cosh},
220 {"exp", math_exp},
221 {"fabs", math_fabs},
222 {"floor", math_floor},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223 {"fmod", math_fmod},
Guido van Rossumd18ad581991-10-24 14:57:21 +0000224 {"frexp", math_frexp},
Guido van Rossum411a8bd1994-10-20 22:00:28 +0000225 {"hypot", math_hypot},
Guido van Rossumd18ad581991-10-24 14:57:21 +0000226 {"ldexp", math_ldexp},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 {"log", math_log},
228 {"log10", math_log10},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 {"modf", math_modf},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 {"pow", math_pow},
231 {"sin", math_sin},
232 {"sinh", math_sinh},
233 {"sqrt", math_sqrt},
234 {"tan", math_tan},
235 {"tanh", math_tanh},
236 {NULL, NULL} /* sentinel */
237};
238
239void
240initmath()
241{
242 object *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000243
244 m = initmodule("math", math_methods);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245 d = getmoduledict(m);
Guido van Rossumeb38d241990-11-18 17:36:45 +0000246 dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
247 DECREF(v);
248 dictinsert(d, "e", v = newfloatobject(exp(1.0)));
249 DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250}