blob: e45e64f9ade404e77bc6a30f9d7bb4f2b1b44a30 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Math module -- standard C math library functions, pi and e */
2
Guido van Rossum3f5da241990-12-20 15:06:42 +00003#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004
Guido van Rossum801f4731990-12-20 23:09:14 +00005#include <errno.h>
6#ifndef errno
7extern int errno;
8#endif
9
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000010#include "modsupport.h"
11
Guido van Rossum3f5da241990-12-20 15:06:42 +000012#include <math.h>
13
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000014static int
15getdoublearg(args, px)
16 register object *args;
17 double *px;
18{
19 if (args == NULL)
20 return err_badarg();
21 if (is_floatobject(args)) {
22 *px = getfloatvalue(args);
23 return 1;
24 }
25 if (is_intobject(args)) {
26 *px = getintvalue(args);
27 return 1;
28 }
29 return err_badarg();
30}
31
32static int
33get2doublearg(args, px, py)
34 register object *args;
35 double *px, *py;
36{
37 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2)
38 return err_badarg();
39 return getdoublearg(gettupleitem(args, 0), px) &&
40 getdoublearg(gettupleitem(args, 1), py);
41}
42
43static object *
44math_1(args, func)
45 object *args;
46 double (*func) FPROTO((double));
47{
48 double x;
49 if (!getdoublearg(args, &x))
50 return NULL;
51 errno = 0;
52 x = (*func)(x);
53 if (errno != 0)
54 return NULL;
55 else
56 return newfloatobject(x);
57}
58
59static object *
60math_2(args, func)
61 object *args;
62 double (*func) FPROTO((double, double));
63{
64 double x, y;
65 if (!get2doublearg(args, &x, &y))
66 return NULL;
67 errno = 0;
68 x = (*func)(x, y);
69 if (errno != 0)
70 return NULL;
71 else
72 return newfloatobject(x);
73}
74
75#define FUNC1(stubname, func) \
76 static object * stubname(self, args) object *self, *args; { \
77 return math_1(args, func); \
78 }
79
80#define FUNC2(stubname, func) \
81 static object * stubname(self, args) object *self, *args; { \
82 return math_2(args, func); \
83 }
84
85FUNC1(math_acos, acos)
86FUNC1(math_asin, asin)
87FUNC1(math_atan, atan)
88FUNC2(math_atan2, atan2)
89FUNC1(math_ceil, ceil)
90FUNC1(math_cos, cos)
91FUNC1(math_cosh, cosh)
92FUNC1(math_exp, exp)
93FUNC1(math_fabs, fabs)
94FUNC1(math_floor, floor)
95#if 0
96/* XXX This one is not in the Amoeba library yet, so what the heck... */
97FUNC2(math_fmod, fmod)
98#endif
99FUNC1(math_log, log)
100FUNC1(math_log10, log10)
101FUNC2(math_pow, pow)
102FUNC1(math_sin, sin)
103FUNC1(math_sinh, sinh)
104FUNC1(math_sqrt, sqrt)
105FUNC1(math_tan, tan)
106FUNC1(math_tanh, tanh)
107
108#if 0
109/* What about these? */
110double frexp(double x, int *i);
111double ldexp(double x, int n);
112double modf(double x, double *i);
113#endif
114
115static struct methodlist math_methods[] = {
116 {"acos", math_acos},
117 {"asin", math_asin},
118 {"atan", math_atan},
119 {"atan2", math_atan2},
120 {"ceil", math_ceil},
121 {"cos", math_cos},
122 {"cosh", math_cosh},
123 {"exp", math_exp},
124 {"fabs", math_fabs},
125 {"floor", math_floor},
126#if 0
127 {"fmod", math_fmod},
128 {"frexp", math_freqp},
129 {"ldexp", math_ldexp},
130#endif
131 {"log", math_log},
132 {"log10", math_log10},
133#if 0
134 {"modf", math_modf},
135#endif
136 {"pow", math_pow},
137 {"sin", math_sin},
138 {"sinh", math_sinh},
139 {"sqrt", math_sqrt},
140 {"tan", math_tan},
141 {"tanh", math_tanh},
142 {NULL, NULL} /* sentinel */
143};
144
145void
146initmath()
147{
148 object *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000149
150 m = initmodule("math", math_methods);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 d = getmoduledict(m);
Guido van Rossumeb38d241990-11-18 17:36:45 +0000152 dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
153 DECREF(v);
154 dictinsert(d, "e", v = newfloatobject(exp(1.0)));
155 DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156}