mathmodule.c 13.3 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" /* just for SHIFT */
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
#ifdef _OSF_SOURCE
/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
extern double copysign(double, double);
#endif

20 21 22 23 24 25
/* 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)
26
{
27
	int result = 1;	/* presumption of guilt */
28
	assert(errno);	/* non-zero errno is a precondition for calling */
29
	if (errno == EDOM)
Barry Warsaw's avatar
Barry Warsaw committed
30
		PyErr_SetString(PyExc_ValueError, "math domain error");
31

32 33 34 35
	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
36 37 38 39 40 41
		 * 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).
42 43
		 */
		if (x)
44
			PyErr_SetString(PyExc_OverflowError,
45 46 47 48
					"math range error");
		else
			result = 0;
	}
49
	else
Barry Warsaw's avatar
Barry Warsaw committed
50 51
                /* Unexpected math error */
		PyErr_SetFromErrno(PyExc_ValueError);
52
	return result;
53 54
}

Barry Warsaw's avatar
Barry Warsaw committed
55
static PyObject *
56 57
math_1_to_whatever(PyObject *arg, double (*func) (double),
                   PyObject *(*from_double_func) (double))
Guido van Rossum's avatar
Guido van Rossum committed
58
{
59 60
	double x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
Guido van Rossum's avatar
Guido van Rossum committed
61 62
		return NULL;
	errno = 0;
63
	PyFPE_START_PROTECT("in math_1", return 0)
Guido van Rossum's avatar
Guido van Rossum committed
64
	x = (*func)(x);
65
	PyFPE_END_PROTECT(x)
66
	Py_SET_ERRNO_ON_MATH_ERROR(x);
67 68
	if (errno && is_error(x))
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
69
	else
70 71 72 73 74 75 76 77 78 79 80 81 82
        	return (*from_double_func)(x);
}

static PyObject *
math_1(PyObject *arg, double (*func) (double))
{
	return math_1_to_whatever(arg, func, PyFloat_FromDouble);
}

static PyObject *
math_1_to_int(PyObject *arg, double (*func) (double))
{
	return math_1_to_whatever(arg, func, PyLong_FromDouble);
Guido van Rossum's avatar
Guido van Rossum committed
83 84
}

Barry Warsaw's avatar
Barry Warsaw committed
85
static PyObject *
86
math_2(PyObject *args, double (*func) (double, double), char *funcname)
Guido van Rossum's avatar
Guido van Rossum committed
87
{
88
	PyObject *ox, *oy;
Guido van Rossum's avatar
Guido van Rossum committed
89
	double x, y;
90 91 92 93 94
	if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy))
		return NULL;
	x = PyFloat_AsDouble(ox);
	y = PyFloat_AsDouble(oy);
	if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
Guido van Rossum's avatar
Guido van Rossum committed
95 96
		return NULL;
	errno = 0;
97
	PyFPE_START_PROTECT("in math_2", return 0)
Guido van Rossum's avatar
Guido van Rossum committed
98
	x = (*func)(x, y);
99
	PyFPE_END_PROTECT(x)
100
	Py_SET_ERRNO_ON_MATH_ERROR(x);
101 102
	if (errno && is_error(x))
		return NULL;
Guido van Rossum's avatar
Guido van Rossum committed
103
	else
Barry Warsaw's avatar
Barry Warsaw committed
104
		return PyFloat_FromDouble(x);
Guido van Rossum's avatar
Guido van Rossum committed
105 106
}

107 108
#define FUNC1(funcname, func, docstring) \
	static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
109
		return math_1(args, func); \
110
	}\
111
        PyDoc_STRVAR(math_##funcname##_doc, docstring);
Guido van Rossum's avatar
Guido van Rossum committed
112

113 114
#define FUNC2(funcname, func, docstring) \
	static PyObject * math_##funcname(PyObject *self, PyObject *args) { \
115
		return math_2(args, func, #funcname); \
116
	}\
117
        PyDoc_STRVAR(math_##funcname##_doc, docstring);
118

119
FUNC1(acos, acos,
120
      "acos(x)\n\nReturn the arc cosine (measured in radians) of x.")
121
FUNC1(asin, asin,
122
      "asin(x)\n\nReturn the arc sine (measured in radians) of x.")
123
FUNC1(atan, atan,
124
      "atan(x)\n\nReturn the arc tangent (measured in radians) of x.")
125
FUNC2(atan2, atan2,
126 127
      "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.")
128 129 130 131 132 133

static PyObject * math_ceil(PyObject *self, PyObject *number) {
	static PyObject *ceil_str = NULL;
	PyObject *method;

	if (ceil_str == NULL) {
134
		ceil_str = PyUnicode_InternFromString("__ceil__");
135 136 137 138
		if (ceil_str == NULL)
			return NULL;
	}

139
	method = _PyType_Lookup(Py_TYPE(number), ceil_str);
140
	if (method == NULL)
141
		return math_1_to_int(number, ceil);
142 143 144 145 146
	else
		return PyObject_CallFunction(method, "O", number);
}

PyDoc_STRVAR(math_ceil_doc,
147
	     "ceil(x)\n\nReturn the ceiling of x as an int.\n"
148 149
	     "This is the smallest integral value >= x.");

150
FUNC1(cos, cos,
151
      "cos(x)\n\nReturn the cosine of x (measured in radians).")
152
FUNC1(cosh, cosh,
153
      "cosh(x)\n\nReturn the hyperbolic cosine of x.")
154

155
#ifdef MS_WINDOWS
156 157
#  define copysign _copysign
#  define HAVE_COPYSIGN 1
158
#endif
159 160 161
#ifdef HAVE_COPYSIGN
FUNC2(copysign, copysign,
      "copysign(x,y)\n\nReturn x with the sign of y.");
162
#endif
163

164
FUNC1(exp, exp,
165
      "exp(x)\n\nReturn e raised to the power of x.")
166
FUNC1(fabs, fabs,
167
      "fabs(x)\n\nReturn the absolute value of the float x.")
168 169 170 171 172 173

static PyObject * math_floor(PyObject *self, PyObject *number) {
	static PyObject *floor_str = NULL;
	PyObject *method;

	if (floor_str == NULL) {
174
		floor_str = PyUnicode_InternFromString("__floor__");
175 176 177 178
		if (floor_str == NULL)
			return NULL;
	}

179
	method = _PyType_Lookup(Py_TYPE(number), floor_str);
180
	if (method == NULL)
181
        	return math_1_to_int(number, floor);
182 183 184 185 186
	else
		return PyObject_CallFunction(method, "O", number);
}

PyDoc_STRVAR(math_floor_doc,
187
	     "floor(x)\n\nReturn the floor of x as an int.\n"
188 189
	     "This is the largest integral value <= x.");

190
FUNC2(fmod, fmod,
191 192
      "fmod(x,y)\n\nReturn fmod(x, y), according to platform C."
      "  x % y may differ.")
193
FUNC2(hypot, hypot,
194
      "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
195
FUNC2(pow, pow,
196
      "pow(x,y)\n\nReturn x**y (x to the power of y).")
197
FUNC1(sin, sin,
198
      "sin(x)\n\nReturn the sine of x (measured in radians).")
199
FUNC1(sinh, sinh,
200
      "sinh(x)\n\nReturn the hyperbolic sine of x.")
201
FUNC1(sqrt, sqrt,
202
      "sqrt(x)\n\nReturn the square root of x.")
203
FUNC1(tan, tan,
204
      "tan(x)\n\nReturn the tangent of x (measured in radians).")
205
FUNC1(tanh, tanh,
206
      "tanh(x)\n\nReturn the hyperbolic tangent of x.")
Guido van Rossum's avatar
Guido van Rossum committed
207

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
static PyObject *
math_trunc(PyObject *self, PyObject *number)
{
	static PyObject *trunc_str = NULL;
	PyObject *trunc;

	if (Py_TYPE(number)->tp_dict == NULL) {
		if (PyType_Ready(Py_TYPE(number)) < 0)
			return NULL;
	}

	if (trunc_str == NULL) {
		trunc_str = PyUnicode_InternFromString("__trunc__");
		if (trunc_str == NULL)
			return NULL;
	}

	trunc = _PyType_Lookup(Py_TYPE(number), trunc_str);
	if (trunc == NULL) {
		PyErr_Format(PyExc_TypeError,
			     "type %.100s doesn't define __trunc__ method",
			     Py_TYPE(number)->tp_name);
		return NULL;
	}
	return PyObject_CallFunctionObjArgs(trunc, number, NULL);
}

PyDoc_STRVAR(math_trunc_doc,
"trunc(x:Real) -> Integral\n"
"\n"
Christian Heimes's avatar
Christian Heimes committed
238
"Truncates x to the nearest Integral toward 0. Uses the __trunc__ magic method.");
239

Barry Warsaw's avatar
Barry Warsaw committed
240
static PyObject *
241
math_frexp(PyObject *self, PyObject *arg)
242 243
{
	int i;
244 245
	double x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
246 247 248
		return NULL;
	errno = 0;
	x = frexp(x, &i);
249
	Py_SET_ERRNO_ON_MATH_ERROR(x);
250 251 252 253
	if (errno && is_error(x))
		return NULL;
	else
		return Py_BuildValue("(di)", x, i);
254 255
}

256
PyDoc_STRVAR(math_frexp_doc,
257 258 259 260
"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"
261
"If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.");
262

Barry Warsaw's avatar
Barry Warsaw committed
263
static PyObject *
264
math_ldexp(PyObject *self, PyObject *args)
265
{
Guido van Rossum's avatar
Guido van Rossum committed
266 267
	double x;
	int exp;
268
	if (! PyArg_ParseTuple(args, "di:ldexp", &x, &exp))
269 270
		return NULL;
	errno = 0;
271
	PyFPE_START_PROTECT("ldexp", return 0)
Guido van Rossum's avatar
Guido van Rossum committed
272
	x = ldexp(x, exp);
273
	PyFPE_END_PROTECT(x)
274
	Py_SET_ERRNO_ON_MATH_ERROR(x);
275 276
	if (errno && is_error(x))
		return NULL;
277
	else
Barry Warsaw's avatar
Barry Warsaw committed
278
		return PyFloat_FromDouble(x);
279 280
}

281 282
PyDoc_STRVAR(math_ldexp_doc,
"ldexp(x, i) -> x * (2**i)");
283

Barry Warsaw's avatar
Barry Warsaw committed
284
static PyObject *
285
math_modf(PyObject *self, PyObject *arg)
286
{
287 288
	double y, x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
289 290 291
		return NULL;
	errno = 0;
	x = modf(x, &y);
292
	Py_SET_ERRNO_ON_MATH_ERROR(x);
293 294 295 296
	if (errno && is_error(x))
		return NULL;
	else
		return Py_BuildValue("(dd)", x, y);
297
}
Guido van Rossum's avatar
Guido van Rossum committed
298

299
PyDoc_STRVAR(math_modf_doc,
300 301 302
"modf(x)\n"
"\n"
"Return the fractional and integer parts of x.  Both results carry the sign\n"
303
"of x.  The integer part is returned as a real.");
304

305 306 307 308 309 310 311 312 313
/* 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*
314
loghelper(PyObject* arg, double (*func)(double), char *funcname)
315 316 317 318 319 320 321 322 323 324 325
{
	/* 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;
		}
326 327 328
		/* Value is ~= x * 2**(e*PyLong_SHIFT), so the log ~=
		   log(x) + log(2) * e * PyLong_SHIFT.
		   CAUTION:  e*PyLong_SHIFT may overflow using int arithmetic,
329
		   so force use of double. */
330
		x = func(x) + (e * (double)PyLong_SHIFT) * func(2.0);
331 332 333 334
		return PyFloat_FromDouble(x);
	}

	/* Else let libm handle it by itself. */
335
	return math_1(arg, func);
336 337 338 339 340
}

static PyObject *
math_log(PyObject *self, PyObject *args)
{
341 342 343 344 345
	PyObject *arg;
	PyObject *base = NULL;
	PyObject *num, *den;
	PyObject *ans;

346
	if (!PyArg_UnpackTuple(args, "log", 1, 2, &arg, &base))
347 348
		return NULL;

349 350 351
	num = loghelper(arg, log, "log");
	if (num == NULL || base == NULL)
		return num;
352

353
	den = loghelper(base, log, "log");
354 355 356 357 358
	if (den == NULL) {
		Py_DECREF(num);
		return NULL;
	}

359
	ans = PyNumber_TrueDivide(num, den);
360 361 362
	Py_DECREF(num);
	Py_DECREF(den);
	return ans;
363 364
}

365
PyDoc_STRVAR(math_log_doc,
366 367
"log(x[, base]) -> the logarithm of x to the given base.\n\
If the base not specified, returns the natural logarithm (base e) of x.");
368 369

static PyObject *
370
math_log10(PyObject *self, PyObject *arg)
371
{
372
	return loghelper(arg, log10, "log10");
373 374
}

375 376
PyDoc_STRVAR(math_log10_doc,
"log10(x) -> the base 10 logarithm of x.");
377

378 379
static const double degToRad = Py_MATH_PI / 180.0;
static const double radToDeg = 180.0 / Py_MATH_PI;
380 381

static PyObject *
382
math_degrees(PyObject *self, PyObject *arg)
383
{
384 385
	double x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
386
		return NULL;
387
	return PyFloat_FromDouble(x * radToDeg);
388 389
}

390 391
PyDoc_STRVAR(math_degrees_doc,
"degrees(x) -> converts angle x from radians to degrees");
392 393

static PyObject *
394
math_radians(PyObject *self, PyObject *arg)
395
{
396 397
	double x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
398 399 400 401
		return NULL;
	return PyFloat_FromDouble(x * degToRad);
}

402 403
PyDoc_STRVAR(math_radians_doc,
"radians(x) -> converts angle x from degrees to radians");
404

405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
static PyObject *
math_isnan(PyObject *self, PyObject *arg)
{
	double x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
		return NULL;
	return PyBool_FromLong((long)Py_IS_NAN(x));
}

PyDoc_STRVAR(math_isnan_doc,
"isnan(x) -> bool\n\
Checks if float x is not a number (NaN)");

static PyObject *
math_isinf(PyObject *self, PyObject *arg)
{
	double x = PyFloat_AsDouble(arg);
	if (x == -1.0 && PyErr_Occurred())
		return NULL;
	return PyBool_FromLong((long)Py_IS_INFINITY(x));
}

PyDoc_STRVAR(math_isinf_doc,
"isinf(x) -> bool\n\
Checks if float x is infinite (positive or negative)");


Barry Warsaw's avatar
Barry Warsaw committed
432
static PyMethodDef math_methods[] = {
433 434 435
	{"acos",	math_acos,	METH_O,		math_acos_doc},
	{"asin",	math_asin,	METH_O,		math_asin_doc},
	{"atan",	math_atan,	METH_O,		math_atan_doc},
436
	{"atan2",	math_atan2,	METH_VARARGS,	math_atan2_doc},
437
	{"ceil",	math_ceil,	METH_O,		math_ceil_doc},
438
#ifdef HAVE_COPYSIGN
439 440
	{"copysign",	math_copysign,	METH_VARARGS,	math_copysign_doc},
#endif
441 442 443 444 445 446
	{"cos",		math_cos,	METH_O,		math_cos_doc},
	{"cosh",	math_cosh,	METH_O,		math_cosh_doc},
	{"degrees",	math_degrees,	METH_O,		math_degrees_doc},
	{"exp",		math_exp,	METH_O,		math_exp_doc},
	{"fabs",	math_fabs,	METH_O,		math_fabs_doc},
	{"floor",	math_floor,	METH_O,		math_floor_doc},
447
	{"fmod",	math_fmod,	METH_VARARGS,	math_fmod_doc},
448
	{"frexp",	math_frexp,	METH_O,		math_frexp_doc},
449
	{"hypot",	math_hypot,	METH_VARARGS,	math_hypot_doc},
450 451
	{"isinf",	math_isinf,	METH_O,		math_isinf_doc},
	{"isnan",	math_isnan,	METH_O,		math_isnan_doc},
452 453
	{"ldexp",	math_ldexp,	METH_VARARGS,	math_ldexp_doc},
	{"log",		math_log,	METH_VARARGS,	math_log_doc},
454 455
	{"log10",	math_log10,	METH_O,		math_log10_doc},
	{"modf",	math_modf,	METH_O,		math_modf_doc},
456
	{"pow",		math_pow,	METH_VARARGS,	math_pow_doc},
457 458 459 460 461 462
	{"radians",	math_radians,	METH_O,		math_radians_doc},
	{"sin",		math_sin,	METH_O,		math_sin_doc},
	{"sinh",	math_sinh,	METH_O,		math_sinh_doc},
	{"sqrt",	math_sqrt,	METH_O,		math_sqrt_doc},
	{"tan",		math_tan,	METH_O,		math_tan_doc},
	{"tanh",	math_tanh,	METH_O,		math_tanh_doc},
463
 	{"trunc",	math_trunc,	METH_O,		math_trunc_doc},
Guido van Rossum's avatar
Guido van Rossum committed
464 465 466
	{NULL,		NULL}		/* sentinel */
};

467

468
PyDoc_STRVAR(module_doc,
469
"This module is always available.  It provides access to the\n"
470
"mathematical functions defined by the C standard.");
471

472
PyMODINIT_FUNC
473
initmath(void)
Guido van Rossum's avatar
Guido van Rossum committed
474
{
Barry Warsaw's avatar
Barry Warsaw committed
475
	PyObject *m, *d, *v;
476

477
	m = Py_InitModule3("math", math_methods, module_doc);
478 479
	if (m == NULL)
		goto finally;
Barry Warsaw's avatar
Barry Warsaw committed
480
	d = PyModule_GetDict(m);
481 482
	if (d == NULL)
		goto finally;
483

484
        if (!(v = PyFloat_FromDouble(Py_MATH_PI)))
485 486 487
                goto finally;
	if (PyDict_SetItemString(d, "pi", v) < 0)
                goto finally;
Barry Warsaw's avatar
Barry Warsaw committed
488
	Py_DECREF(v);
489

490
        if (!(v = PyFloat_FromDouble(Py_MATH_E)))
491
                goto finally;
492
	if (PyDict_SetItemString(d, "e", v) < 0)
493
                goto finally;
Barry Warsaw's avatar
Barry Warsaw committed
494
	Py_DECREF(v);
495 496

  finally:
497
	return;
Guido van Rossum's avatar
Guido van Rossum committed
498
}