blob: e811088264f35aae1b136b3dbdf51db06a78fe2e [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 Rossum85a5fbb1990-10-14 12:07:46 +00005#include "modsupport.h"
6
Guido van Rossum3f5da241990-12-20 15:06:42 +00007#include <math.h>
8
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00009static int
10getdoublearg(args, px)
11 register object *args;
12 double *px;
13{
14 if (args == NULL)
15 return err_badarg();
16 if (is_floatobject(args)) {
17 *px = getfloatvalue(args);
18 return 1;
19 }
20 if (is_intobject(args)) {
21 *px = getintvalue(args);
22 return 1;
23 }
24 return err_badarg();
25}
26
27static int
28get2doublearg(args, px, py)
29 register object *args;
30 double *px, *py;
31{
32 if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2)
33 return err_badarg();
34 return getdoublearg(gettupleitem(args, 0), px) &&
35 getdoublearg(gettupleitem(args, 1), py);
36}
37
38static 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)
49 return NULL;
50 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)
65 return NULL;
66 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)
90#if 0
91/* 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)
96FUNC2(math_pow, pow)
97FUNC1(math_sin, sin)
98FUNC1(math_sinh, sinh)
99FUNC1(math_sqrt, sqrt)
100FUNC1(math_tan, tan)
101FUNC1(math_tanh, tanh)
102
103#if 0
104/* What about these? */
105double frexp(double x, int *i);
106double ldexp(double x, int n);
107double modf(double x, double *i);
108#endif
109
110static struct methodlist math_methods[] = {
111 {"acos", math_acos},
112 {"asin", math_asin},
113 {"atan", math_atan},
114 {"atan2", math_atan2},
115 {"ceil", math_ceil},
116 {"cos", math_cos},
117 {"cosh", math_cosh},
118 {"exp", math_exp},
119 {"fabs", math_fabs},
120 {"floor", math_floor},
121#if 0
122 {"fmod", math_fmod},
123 {"frexp", math_freqp},
124 {"ldexp", math_ldexp},
125#endif
126 {"log", math_log},
127 {"log10", math_log10},
128#if 0
129 {"modf", math_modf},
130#endif
131 {"pow", math_pow},
132 {"sin", math_sin},
133 {"sinh", math_sinh},
134 {"sqrt", math_sqrt},
135 {"tan", math_tan},
136 {"tanh", math_tanh},
137 {NULL, NULL} /* sentinel */
138};
139
140void
141initmath()
142{
143 object *m, *d, *v;
Guido van Rossum738d4dd1990-10-26 14:59:30 +0000144
145 m = initmodule("math", math_methods);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000146 d = getmoduledict(m);
Guido van Rossumeb38d241990-11-18 17:36:45 +0000147 dictinsert(d, "pi", v = newfloatobject(atan(1.0) * 4.0));
148 DECREF(v);
149 dictinsert(d, "e", v = newfloatobject(exp(1.0)));
150 DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151}