blob: 189a0c16e5f3f6aabb04cabe59c811326c5ed4d8 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
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>
30#ifndef errno
31extern int errno;
32#endif
33
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000034#include "modsupport.h"
35
Guido van Rossum3f5da241990-12-20 15:06:42 +000036#include <math.h>
37
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038static object *
39math_1(args, func)
40 object *args;
41 double (*func) FPROTO((double));
42{
43 double x;
44 if (!getdoublearg(args, &x))
45 return NULL;
46 errno = 0;
47 x = (*func)(x);
48 if (errno != 0)
Guido van Rossum1492c271991-07-27 21:38:43 +000049 return err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000050 else
51 return newfloatobject(x);
52}
53
54static object *
55math_2(args, func)
56 object *args;
57 double (*func) FPROTO((double, double));
58{
59 double x, y;
60 if (!get2doublearg(args, &x, &y))
61 return NULL;
62 errno = 0;
63 x = (*func)(x, y);
64 if (errno != 0)
Guido van Rossum1492c271991-07-27 21:38:43 +000065 return err_errno(RuntimeError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066 else
67 return newfloatobject(x);
68}
69
70#define FUNC1(stubname, func) \
71 static object * stubname(self, args) object *self, *args; { \
72 return math_1(args, func); \
73 }
74
75#define FUNC2(stubname, func) \
76 static object * stubname(self, args) object *self, *args; { \
77 return math_2(args, func); \
78 }
79
80FUNC1(math_acos, acos)
81FUNC1(math_asin, asin)
82FUNC1(math_atan, atan)
83FUNC2(math_atan2, atan2)
84FUNC1(math_ceil, ceil)
85FUNC1(math_cos, cos)
86FUNC1(math_cosh, cosh)
87FUNC1(math_exp, exp)
88FUNC1(math_fabs, fabs)
89FUNC1(math_floor, floor)
Guido van Rossumd18ad581991-10-24 14:57:21 +000090#ifndef AMOEBA
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091/* XXX This one is not in the Amoeba library yet, so what the heck... */
92FUNC2(math_fmod, fmod)
93#endif
94FUNC1(math_log, log)
95FUNC1(math_log10, log10)
Guido van Rossum1492c271991-07-27 21:38:43 +000096#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 +000097FUNC2(math_pow, power)
98#else
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099FUNC2(math_pow, pow)
Guido van Rossum76f2f2e1991-06-24 22:23:10 +0000100#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101FUNC1(math_sin, sin)
102FUNC1(math_sinh, sinh)
103FUNC1(math_sqrt, sqrt)
104FUNC1(math_tan, tan)
105FUNC1(math_tanh, tanh)
106
Guido van Rossumd18ad581991-10-24 14:57:21 +0000107double frexp(double, int *);
108double ldexp(double, int);
109double modf(double, double *);
110
111static object *
112math_frexp(self, args)
113 object *self;
114 object *args;
115{
116 object *v;
117 double x;
118 int i;
119 if (!getdoublearg(args, &x))
120 return NULL;
121 errno = 0;
122 x = frexp(x, &i);
123 if (errno != 0)
124 return err_errno(RuntimeError);
125 v = newtupleobject(2);
126 if (v != NULL) {
127 settupleitem(v, 0, newfloatobject(x));
128 settupleitem(v, 1, newintobject((long)i));
129 if (err_occurred()) {
130 DECREF(v);
131 v = NULL;
132 }
133 }
134 return v;
135}
136
137static object *
138math_ldexp(self, args)
139 object *self;
140 object *args;
141{
142 double x, y;
143 /* Cheat -- allow float as second argument */
144 if (!get2doublearg(args, &x, &y))
145 return NULL;
146 errno = 0;
147 x = ldexp(x, (int)y);
148 if (errno != 0)
149 return err_errno(RuntimeError);
150 else
151 return newfloatobject(x);
152}
153
154static object *
155math_modf(self, args)
156 object *self;
157 object *args;
158{
159 object *v;
160 double x, y;
161 if (!getdoublearg(args, &x))
162 return NULL;
163 errno = 0;
164 x = modf(x, &y);
165 if (errno != 0)
166 return err_errno(RuntimeError);
167 v = newtupleobject(2);
168 if (v != NULL) {
169 settupleitem(v, 0, newfloatobject(x));
170 settupleitem(v, 1, newfloatobject(y));
171 if (err_occurred()) {
172 DECREF(v);
173 v = NULL;
174 }
175 }
176 return v;
177}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178
179static struct methodlist math_methods[] = {
180 {"acos", math_acos},
181 {"asin", math_asin},
182 {"atan", math_atan},
183 {"atan2", math_atan2},
184 {"ceil", math_ceil},
185 {"cos", math_cos},
186 {"cosh", math_cosh},
187 {"exp", math_exp},
188 {"fabs", math_fabs},
189 {"floor", math_floor},
Guido van Rossumd18ad581991-10-24 14:57:21 +0000190#ifndef AMOEBA
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 {"fmod", math_fmod},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192#endif
Guido van Rossumd18ad581991-10-24 14:57:21 +0000193 {"frexp", math_frexp},
194 {"ldexp", math_ldexp},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000195 {"log", math_log},
196 {"log10", math_log10},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 {"modf", math_modf},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198 {"pow", math_pow},
199 {"sin", math_sin},
200 {"sinh", math_sinh},
201 {"sqrt", math_sqrt},
202 {"tan", math_tan},
203 {"tanh", math_tanh},
204 {NULL, NULL} /* sentinel */
205};
206
207void
208initmath()
209{
210 object *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000211
212 m = initmodule("math", math_methods);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 d = getmoduledict(m);
Guido van Rossumeb38d241990-11-18 17:36:45 +0000214 dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
215 DECREF(v);
216 dictinsert(d, "e", v = newfloatobject(exp(1.0)));
217 DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000218}