mathmodule.c 10.1 KB
Newer Older
Guido van Rossum's avatar
Guido van Rossum committed
1 2
/* Math module -- standard C math library functions, pi and e */

Barry Warsaw's avatar
Barry Warsaw committed
3
#include "Python.h"
4
#include "longintrepr.h"
Guido van Rossum's avatar
Guido van Rossum committed
5

Guido van Rossum's avatar
Guido van Rossum committed
6
#ifndef _MSC_VER
7
#ifndef __STDC__
8 9 10 11
extern double fmod (double, double);
extern double frexp (double, int *);
extern double ldexp (double, int);
extern double modf (double, double *);
Guido van Rossum's avatar
Guido van Rossum committed
12 13 14
#endif /* __STDC__ */
#endif /* _MSC_VER */

15 16 17 18 19 20
/* Call is_error when errno != 0, and where x is the result libm
 * returned.  is_error will usually set up an exception and return
 * true (1), but may return false (0) without setting up an exception.
 */
static int
is_error(double x)
21
{
22
	int result = 1;	/* presumption of guilt */
23
	assert(errno);	/* non-zero errno is a precondition for calling */
24
	if (errno == EDOM)
Barry Warsaw's avatar
Barry Warsaw committed
25
		PyErr_SetString(PyExc_ValueError, "math domain error");
26

27 28 29 30
	else if (errno == ERANGE) {
		/* ANSI C generally requires libm functions to set ERANGE
		 * on overflow, but also generally *allows* them to set
		 * ERANGE on underflow too.  There's no consistency about
31 32 33 34 35 36
		 * the latter across platforms.
		 * Alas, C99 never requires that errno be set.
		 * Here we suppress the underflow errors (libm functions
		 * should return a zero on underflow, and +- HUGE_VAL on
		 * overflow, so testing the result for zero suffices to
		 * distinguish the cases).
37 38
		 */
		if (x)
39
			PyErr_SetString(PyExc_OverflowError,
40 41 42 43
					"math range error");
		else
			result = 0;
	}
44
	else
Barry Warsaw's avatar
Barry Warsaw committed
45 46
                /* Unexpected math error */
		PyErr_SetFromErrno(PyExc_ValueError);
47
	return result;
48 49
}

Barry Warsaw's avatar
Barry Warsaw committed
50
static PyObject *
51
math_1(PyObject *args, double (*func) (double), char *argsfmt)
Guido van Rossum's avatar
Guido van Rossum committed
52 53
{
	double x;
54
	if (!  PyArg_ParseTuple(args, argsfmt, &x))
Guido van Rossum's avatar
Guido van Rossum committed
55 56
		return NULL;
	errno = 0;
57
	PyFPE_START_PROTECT("in math_1", return 0)
Guido van Rossum's avatar
Guido van Rossum committed
58
	x = (*func)(x);
59
	PyFPE_END_PROTECT(x)
60
	Py_SET_ERANGE_IF_OVERFLOW(x);
61 62
	if (errno && is_error(x))
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
63
	else
Barry Warsaw's avatar
Barry Warsaw committed
64
		return PyFloat_FromDouble(x);
Guido van Rossum's avatar
Guido van Rossum committed
65 66
}

Barry Warsaw's avatar
Barry Warsaw committed
67
static PyObject *
68
math_2(PyObject *args, double (*func) (double, double), char *argsfmt)
Guido van Rossum's avatar
Guido van Rossum committed
69 70
{
	double x, y;
71
	if (! PyArg_ParseTuple(args, argsfmt, &x, &y))
Guido van Rossum's avatar
Guido van Rossum committed
72 73
		return NULL;
	errno = 0;
74
	PyFPE_START_PROTECT("in math_2", return 0)
Guido van Rossum's avatar
Guido van Rossum committed
75
	x = (*func)(x, y);
76
	PyFPE_END_PROTECT(x)
77
	Py_SET_ERANGE_IF_OVERFLOW(x);
78 79
	if (errno && is_error(x))
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
80
	else
Barry Warsaw's avatar
Barry Warsaw committed
81
		return PyFloat_FromDouble(x);
Guido van Rossum's avatar
Guido van Rossum committed
82 83
}

84 85 86
#define FUNC1(funcname, func, docstring) \
	static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
		return math_1(args, func, "d:" #funcname); \
87
	}\
88
        PyDoc_STRVAR(math_##funcname##_doc, docstring);
Guido van Rossum's avatar
Guido van Rossum committed
89

90 91 92
#define FUNC2(funcname, func, docstring) \
	static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
		return math_2(args, func, "dd:" #funcname); \
93
	}\
94
        PyDoc_STRVAR(math_##funcname##_doc, docstring);
95

96
FUNC1(acos, acos,
97
      "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
98
FUNC1(asin, asin,
99
      "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
100
FUNC1(atan, atan,
101
      "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
102
FUNC2(atan2, atan2,
103 104
      "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n"
      "Unlike atan(y/x), the signs of both x and y are considered.")
105
FUNC1(ceil, ceil,
106 107
      "ceil(x)\n\nReturn the ceiling of x as a float.\n"
      "This is the smallest integral value >= x.")
108
FUNC1(cos, cos,
109
      "cos(x)\n\nReturn the cosine of x (measured in radians).")
110
FUNC1(cosh, cosh,
111
      "cosh(x)\n\nReturn the hyperbolic cosine of x.")
112
FUNC1(exp, exp,
113
      "exp(x)\n\nReturn e raised to the power of x.")
114
FUNC1(fabs, fabs,
115
      "fabs(x)\n\nReturn the absolute value of the float x.")
116
FUNC1(floor, floor,
117 118
      "floor(x)\n\nReturn the floor of x as a float.\n"
      "This is the largest integral value <= x.")
119
FUNC2(fmod, fmod,
120 121
      "fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
      "  x % y may differ.")
122
FUNC2(hypot, hypot,
123
      "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
124
#ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */
125
FUNC2(pow, power,
126
      "pow(x,y)\n\nReturn x**y (x to the power of y).")
127
#else
128
FUNC2(pow, pow,
129
      "pow(x,y)\n\nReturn x**y (x to the power of y).")
130
#endif
131
FUNC1(sin, sin,
132
      "sin(x)\n\nReturn the sine of x (measured in radians).")
133
FUNC1(sinh, sinh,
134
      "sinh(x)\n\nReturn the hyperbolic sine of x.")
135
FUNC1(sqrt, sqrt,
136
      "sqrt(x)\n\nReturn the square root of x.")
137
FUNC1(tan, tan,
138
      "tan(x)\n\nReturn the tangent of x (measured in radians).")
139
FUNC1(tanh, tanh,
140
      "tanh(x)\n\nReturn the hyperbolic tangent of x.")
Guido van Rossum's avatar
Guido van Rossum committed
141

Barry Warsaw's avatar
Barry Warsaw committed
142
static PyObject *
143
math_frexp(PyObject *self, PyObject *args)
144 145 146
{
	double x;
	int i;
147
	if (! PyArg_ParseTuple(args, "d:frexp", &x))
148 149 150
		return NULL;
	errno = 0;
	x = frexp(x, &i);
151
	Py_SET_ERANGE_IF_OVERFLOW(x);
152 153 154 155
	if (errno && is_error(x))
		return NULL;
	else
		return Py_BuildValue("(di)", x, i);
156 157
}

158
PyDoc_STRVAR(math_frexp_doc,
159 160 161 162
"frexp(x)\n"
"\n"
"Return the mantissa and exponent of x, as pair (m, e).\n"
"m is a float and e is an int, such that x = m * 2.**e.\n"
163
"If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.");
164

Barry Warsaw's avatar
Barry Warsaw committed
165
static PyObject *
166
math_ldexp(PyObject *self, PyObject *args)
167
{
Guido van Rossum's avatar
Guido van Rossum committed
168 169
	double x;
	int exp;
170
	if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
171 172
		return NULL;
	errno = 0;
173
	PyFPE_START_PROTECT("ldexp", return 0)
Guido van Rossum's avatar
Guido van Rossum committed
174
	x = ldexp(x, exp);
175
	PyFPE_END_PROTECT(x)
176
	Py_SET_ERANGE_IF_OVERFLOW(x);
177 178
	if (errno && is_error(x))
		return NULL;
179
	else
Barry Warsaw's avatar
Barry Warsaw committed
180
		return PyFloat_FromDouble(x);
181 182
}

183 184
PyDoc_STRVAR(math_ldexp_doc,
"ldexp(x, i) -> x * (2**i)");
185

Barry Warsaw's avatar
Barry Warsaw committed
186
static PyObject *
187
math_modf(PyObject *self, PyObject *args)
188 189
{
	double x, y;
190
	if (! PyArg_ParseTuple(args, "d:modf", &x))
191 192
		return NULL;
	errno = 0;
193
#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
194 195 196 197 198
        {
		extended e;
		x = modf(x, &e);
		y = e;
        }
199
#else
200
	x = modf(x, &y);
201
#endif
202
	Py_SET_ERANGE_IF_OVERFLOW(x);
203 204 205 206
	if (errno && is_error(x))
		return NULL;
	else
		return Py_BuildValue("(dd)", x, y);
207
}
Guido van Rossum's avatar
Guido van Rossum committed
208

209
PyDoc_STRVAR(math_modf_doc,
210 211 212
"modf(x)\n"
"\n"
"Return the fractional and integer parts of x.  Both results carry the sign\n"
213
"of x.  The integer part is returned as a real.");
214

215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
/* A decent logarithm is easy to compute even for huge longs, but libm can't
   do that by itself -- loghelper can.  func is log or log10, and name is
   "log" or "log10".  Note that overflow isn't possible:  a long can contain
   no more than INT_MAX * SHIFT bits, so has value certainly less than
   2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is
   small enough to fit in an IEEE single.  log and log10 are even smaller.
*/

static PyObject*
loghelper(PyObject* args, double (*func)(double), char *name)
{
	PyObject *arg;
	char format[16];

	/* See whether this is a long. */
	format[0] = 'O';
	format[1] = ':';
	strcpy(format + 2, name);
	if (! PyArg_ParseTuple(args, format, &arg))
		return NULL;

	/* If it is long, do it ourselves. */
	if (PyLong_Check(arg)) {
		double x;
		int e;
		x = _PyLong_AsScaledDouble(arg, &e);
		if (x <= 0.0) {
			PyErr_SetString(PyExc_ValueError,
					"math domain error");
			return NULL;
		}
		/* Value is ~= x * 2**(e*SHIFT), so the log ~=
		   log(x) + log(2) * e * SHIFT.
		   CAUTION:  e*SHIFT may overflow using int arithmetic,
		   so force use of double. */
250
		x = func(x) + (e * (double)SHIFT) * func(2.0);
251 252 253 254 255 256 257 258 259 260 261 262 263 264
		return PyFloat_FromDouble(x);
	}

	/* Else let libm handle it by itself. */
	format[0] = 'd';
	return math_1(args, func, format);
}

static PyObject *
math_log(PyObject *self, PyObject *args)
{
	return loghelper(args, log, "log");
}

265 266
PyDoc_STRVAR(math_log_doc,
"log(x) -> the natural logarithm (base e) of x.");
267 268 269 270 271 272 273

static PyObject *
math_log10(PyObject *self, PyObject *args)
{
	return loghelper(args, log10, "log10");
}

274 275
PyDoc_STRVAR(math_log10_doc,
"log10(x) -> the base 10 logarithm of x.");
276

277 278 279 280 281 282 283 284 285 286 287
static const double degToRad = 3.141592653589793238462643383 / 180.0;

static PyObject *
math_degrees(PyObject *self, PyObject *args)
{
	double x;
	if (! PyArg_ParseTuple(args, "d:degrees", &x))
		return NULL;
	return PyFloat_FromDouble(x / degToRad);
}

288 289
PyDoc_STRVAR(math_degrees_doc,
"degrees(x) -> converts angle x from radians to degrees");
290 291 292 293 294 295 296 297 298 299

static PyObject *
math_radians(PyObject *self, PyObject *args)
{
	double x;
	if (! PyArg_ParseTuple(args, "d:radians", &x))
		return NULL;
	return PyFloat_FromDouble(x * degToRad);
}

300 301
PyDoc_STRVAR(math_radians_doc,
"radians(x) -> converts angle x from degrees to radians");
302

Barry Warsaw's avatar
Barry Warsaw committed
303
static PyMethodDef math_methods[] = {
304 305 306 307 308 309 310
	{"acos",	math_acos,	METH_VARARGS,	math_acos_doc},
	{"asin",	math_asin,	METH_VARARGS,	math_asin_doc},
	{"atan",	math_atan,	METH_VARARGS,	math_atan_doc},
	{"atan2",	math_atan2,	METH_VARARGS,	math_atan2_doc},
	{"ceil",	math_ceil,	METH_VARARGS,	math_ceil_doc},
	{"cos",		math_cos,	METH_VARARGS,	math_cos_doc},
	{"cosh",	math_cosh,	METH_VARARGS,	math_cosh_doc},
311
	{"degrees",	math_degrees,	METH_VARARGS,	math_degrees_doc},
312 313 314 315 316 317 318 319 320 321 322
	{"exp",		math_exp,	METH_VARARGS,	math_exp_doc},
	{"fabs",	math_fabs,	METH_VARARGS,	math_fabs_doc},
	{"floor",	math_floor,	METH_VARARGS,	math_floor_doc},
	{"fmod",	math_fmod,	METH_VARARGS,	math_fmod_doc},
	{"frexp",	math_frexp,	METH_VARARGS,	math_frexp_doc},
	{"hypot",	math_hypot,	METH_VARARGS,	math_hypot_doc},
	{"ldexp",	math_ldexp,	METH_VARARGS,	math_ldexp_doc},
	{"log",		math_log,	METH_VARARGS,	math_log_doc},
	{"log10",	math_log10,	METH_VARARGS,	math_log10_doc},
	{"modf",	math_modf,	METH_VARARGS,	math_modf_doc},
	{"pow",		math_pow,	METH_VARARGS,	math_pow_doc},
323
	{"radians",	math_radians,	METH_VARARGS,	math_radians_doc},
324 325 326 327 328
	{"sin",		math_sin,	METH_VARARGS,	math_sin_doc},
	{"sinh",	math_sinh,	METH_VARARGS,	math_sinh_doc},
	{"sqrt",	math_sqrt,	METH_VARARGS,	math_sqrt_doc},
	{"tan",		math_tan,	METH_VARARGS,	math_tan_doc},
	{"tanh",	math_tanh,	METH_VARARGS,	math_tanh_doc},
Guido van Rossum's avatar
Guido van Rossum committed
329 330 331
	{NULL,		NULL}		/* sentinel */
};

332

333
PyDoc_STRVAR(module_doc,
334
"This module is always available.  It provides access to the\n"
335
"mathematical functions defined by the C standard.");
336

337
DL_EXPORT(void)
338
initmath(void)
Guido van Rossum's avatar
Guido van Rossum committed
339
{
Barry Warsaw's avatar
Barry Warsaw committed
340
	PyObject *m, *d, *v;
341

342
	m = Py_InitModule3("math", math_methods, module_doc);
Barry Warsaw's avatar
Barry Warsaw committed
343
	d = PyModule_GetDict(m);
344 345 346 347 348

        if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
                goto finally;
	if (PyDict_SetItemString(d, "pi", v) < 0)
                goto finally;
Barry Warsaw's avatar
Barry Warsaw committed
349
	Py_DECREF(v);
350 351 352

        if (!(v = PyFloat_FromDouble(exp(1.0))))
                goto finally;
353
	if (PyDict_SetItemString(d, "e", v) < 0)
354
                goto finally;
Barry Warsaw's avatar
Barry Warsaw committed
355
	Py_DECREF(v);
356 357

  finally:
358
	return;
Guido van Rossum's avatar
Guido van Rossum committed
359
}