blob: c11f8f7db6ee09e45891c9da66d221a5696e1af0 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum6610ad91995-01-04 19:07:38 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Float object implementation */
33
Guido van Rossum2a9096b1990-10-21 22:15:08 +000034/* XXX There should be overflow checks here, but it's hard to check
35 for any kind of float exception without losing portability. */
36
Guido van Rossumc0b618a1997-05-02 03:12:38 +000037#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000038
Guido van Rossum3f5da241990-12-20 15:06:42 +000039#include <ctype.h>
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000040#include "mymath.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Guido van Rossum9575a441993-04-07 14:06:14 +000042#ifdef i860
43/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
44#undef HUGE_VAL
45#endif
46
Guido van Rossum9d81b551996-06-26 18:27:19 +000047#if defined(HUGE_VAL) && !defined(CHECK)
Guido van Rossum7fa52f81991-12-16 15:43:14 +000048#define CHECK(x) if (errno != 0) ; \
49 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
50 else errno = ERANGE
Guido van Rossum9d81b551996-06-26 18:27:19 +000051#endif
52
53#ifndef CHECK
Guido van Rossum7fa52f81991-12-16 15:43:14 +000054#define CHECK(x) /* Don't know how to check */
55#endif
56
Guido van Rossum03093a21994-09-28 15:51:32 +000057#ifdef HAVE_LIMITS_H
58#include <limits.h>
59#endif
60
61#ifndef LONG_MAX
62#define LONG_MAX 0X7FFFFFFFL
63#endif
64
65#ifndef LONG_MIN
66#define LONG_MIN (-LONG_MAX-1)
67#endif
68
Guido van Rossum67ca7011995-02-13 16:38:41 +000069#ifdef __NeXT__
70#ifdef __sparc__
71/*
72 * This works around a bug in the NS/Sparc 3.3 pre-release
73 * limits.h header file.
74 * 10-Feb-1995 bwarsaw@cnri.reston.va.us
75 */
76#undef LONG_MIN
77#define LONG_MIN (-LONG_MAX-1)
78#endif
79#endif
80
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000081#if !defined(__STDC__) && !defined(macintosh)
Guido van Rossumc0b618a1997-05-02 03:12:38 +000082extern double fmod Py_PROTO((double, double));
83extern double pow Py_PROTO((double, double));
Guido van Rossum6923e131990-11-02 17:50:43 +000084#endif
85
Guido van Rossum3c03fa81997-10-31 17:00:30 +000086#ifdef sun
87/* On SunOS4.1 only libm.a exists. Make sure that references to all
88 needed math functions exist in the executable, so that dynamic
89 loading of mathmodule does not fail. */
90double (*_Py_math_funcs_hack[])() = {
91 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor,
92 fmod, log, log10, pow, sin, sinh, sqrt, tan, tanh
93};
94#endif
95
Guido van Rossum93ad0df1997-05-13 21:00:42 +000096/* Special free list -- see comments for same code in intobject.c. */
97static PyFloatObject *free_list = NULL;
Guido van Rossumf61bbc81999-03-12 00:12:21 +000098static PyFloatObject *block_list = NULL;
Guido van Rossum93ad0df1997-05-13 21:00:42 +000099#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000100#define BHEAD_SIZE 8 /* Hope this is enough alignment */
101#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
102#define PyMem_MALLOC malloc
103#define PyMem_FREE free
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000104
105static PyFloatObject *
106fill_free_list()
107{
108 PyFloatObject *p, *q;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000109 p = (PyFloatObject *)PyMem_MALLOC(BLOCK_SIZE);
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000110 if (p == NULL)
111 return (PyFloatObject *)PyErr_NoMemory();
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000112 *(PyFloatObject **)p = block_list;
113 block_list = p;
114 p = (PyFloatObject *)((char *)p + BHEAD_SIZE);
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000115 q = p + N_FLOATOBJECTS;
116 while (--q > p)
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000117 q->ob_type = (struct _typeobject *)(q-1);
118 q->ob_type = NULL;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000119 return p + N_FLOATOBJECTS - 1;
120}
121
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000122PyObject *
Guido van Rossum07e3a7e1995-02-27 10:13:37 +0000123#ifdef __SC__
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000124PyFloat_FromDouble(double fval)
Guido van Rossum07e3a7e1995-02-27 10:13:37 +0000125#else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000126PyFloat_FromDouble(fval)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 double fval;
Guido van Rossum07e3a7e1995-02-27 10:13:37 +0000128#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129{
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000130 register PyFloatObject *op;
131 if (free_list == NULL) {
132 if ((free_list = fill_free_list()) == NULL)
133 return NULL;
134 }
135 op = free_list;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000136 free_list = (PyFloatObject *)op->ob_type;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000137 op->ob_type = &PyFloat_Type;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000138 op->ob_fval = fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000139 _Py_NewReference(op);
140 return (PyObject *) op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141}
142
Guido van Rossum234f9421993-06-17 12:35:49 +0000143static void
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000144float_dealloc(op)
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000145 PyFloatObject *op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000146{
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000147 op->ob_type = (struct _typeobject *)free_list;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000148 free_list = op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000149}
150
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151double
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000152PyFloat_AsDouble(op)
153 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000155 PyNumberMethods *nb;
156 PyFloatObject *fo;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157 double val;
158
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000159 if (op && PyFloat_Check(op))
160 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161
162 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
163 nb->nb_float == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000164 PyErr_BadArgument();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 return -1;
166 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000168 fo = (PyFloatObject*) (*nb->nb_float) (op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000169 if (fo == NULL)
170 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000171 if (!PyFloat_Check(fo)) {
172 PyErr_SetString(PyExc_TypeError,
173 "nb_float should return float object");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174 return -1;
175 }
176
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 val = PyFloat_AS_DOUBLE(fo);
178 Py_DECREF(fo);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179
180 return val;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000181}
182
183/* Methods */
184
Guido van Rossum27dec7e1991-06-04 19:42:53 +0000185void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186PyFloat_AsString(buf, v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000187 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000188 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189{
190 register char *cp;
191 /* Subroutine for float_repr and float_print.
192 We want float numbers to be recognizable as such,
193 i.e., they should contain a decimal point or an exponent.
194 However, %g may print the number as an integer;
195 in such cases, we append ".0" to the string. */
196 sprintf(buf, "%.12g", v->ob_fval);
197 cp = buf;
198 if (*cp == '-')
199 cp++;
200 for (; *cp != '\0'; cp++) {
201 /* Any non-digit means it's not an integer;
202 this takes care of NAN and INF as well. */
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000203 if (!isdigit(Py_CHARMASK(*cp)))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 break;
205 }
206 if (*cp == '\0') {
207 *cp++ = '.';
208 *cp++ = '0';
209 *cp++ = '\0';
210 }
211}
212
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000213/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000214static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215float_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000217 FILE *fp;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000218 int flags; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000219{
220 char buf[100];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 PyFloat_AsString(buf, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 fputs(buf, fp);
Guido van Rossum90933611991-06-07 16:10:43 +0000223 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224}
225
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000226static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227float_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229{
230 char buf[100];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 PyFloat_AsString(buf, v);
232 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233}
234
235static int
236float_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 PyFloatObject *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238{
239 double i = v->ob_fval;
240 double j = w->ob_fval;
241 return (i < j) ? -1 : (i > j) ? 1 : 0;
242}
243
Guido van Rossum9bfef441993-03-29 10:43:31 +0000244static long
245float_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 PyFloatObject *v;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000247{
248 double intpart, fractpart;
249 int expo;
250 long x;
251 /* This is designed so that Python numbers with the same
252 value hash to the same value, otherwise comparisons
253 of mapping keys will turn out weird */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
256{
257 extended e;
258 fractpart = modf(v->ob_fval, &e);
259 intpart = e;
260}
261#else
Guido van Rossum9bfef441993-03-29 10:43:31 +0000262 fractpart = modf(v->ob_fval, &intpart);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#endif
264
Guido van Rossum9bfef441993-03-29 10:43:31 +0000265 if (fractpart == 0.0) {
266 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
267 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000268 PyObject *w = PyLong_FromDouble(v->ob_fval);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000269 if (w == NULL)
270 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000271 x = PyObject_Hash(w);
272 Py_DECREF(w);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000273 return x;
274 }
275 x = (long)intpart;
276 }
277 else {
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000278 /* Note -- if you change this code, also change the copy
279 in complexobject.c */
280 long hipart;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000281 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000282 fractpart = fractpart * 2147483648.0; /* 2**31 */
283 hipart = (long)fractpart; /* Take the top 32 bits */
284 fractpart = (fractpart - (double)hipart) * 2147483648.0;
285 /* Get the next 32 bits */
286 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
287 /* Combine everything */
Guido van Rossum9bfef441993-03-29 10:43:31 +0000288 }
289 if (x == -1)
290 x = -2;
291 return x;
292}
293
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000294static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295float_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000296 PyFloatObject *v;
297 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000299 double result;
300 PyFPE_START_PROTECT("add", return 0)
301 result = v->ob_fval + w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000302 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304}
305
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307float_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000308 PyFloatObject *v;
309 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000311 double result;
312 PyFPE_START_PROTECT("subtract", return 0)
313 result = v->ob_fval - w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000314 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316}
317
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000318static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319float_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000320 PyFloatObject *v;
321 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000323 double result;
324
325 PyFPE_START_PROTECT("multiply", return 0)
326 result = v->ob_fval * w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000327 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329}
330
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000331static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332float_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000333 PyFloatObject *v;
334 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000336 double result;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000337 if (w->ob_fval == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000338 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339 return NULL;
340 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000341 PyFPE_START_PROTECT("divide", return 0)
342 result = v->ob_fval / w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000343 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000344 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345}
346
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348float_rem(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 PyFloatObject *v;
350 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351{
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000352 double vx, wx;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000353 double /* div, */ mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000354 wx = w->ob_fval;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 return NULL;
358 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000359 PyFPE_START_PROTECT("modulo", return 0)
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000360 vx = v->ob_fval;
361 mod = fmod(vx, wx);
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000362 /* div = (vx - mod) / wx; */
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000363 if (wx*mod < 0) {
364 mod += wx;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000365 /* div -= 1.0; */
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000366 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000367 PyFPE_END_PROTECT(mod)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 return PyFloat_FromDouble(mod);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369}
370
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000371static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000372float_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000373 PyFloatObject *v;
374 PyFloatObject *w;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000375{
Guido van Rossum15ecff41991-10-20 20:16:45 +0000376 double vx, wx;
377 double div, mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000378 wx = w->ob_fval;
Guido van Rossum15ecff41991-10-20 20:16:45 +0000379 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
Guido van Rossum15ecff41991-10-20 20:16:45 +0000381 return NULL;
382 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000383 PyFPE_START_PROTECT("divmod", return 0)
Guido van Rossum15ecff41991-10-20 20:16:45 +0000384 vx = v->ob_fval;
385 mod = fmod(vx, wx);
386 div = (vx - mod) / wx;
387 if (wx*mod < 0) {
388 mod += wx;
389 div -= 1.0;
390 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000391 PyFPE_END_PROTECT(div)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000392 return Py_BuildValue("(dd)", div, mod);
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000393}
394
Guido van Rossum363078a1996-05-24 20:45:01 +0000395static double powu(x, n)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000396 double x;
397 long n;
398{
399 double r = 1.;
400 double p = x;
401 long mask = 1;
402 while (mask > 0 && n >= mask) {
403 if (n & mask)
404 r *= p;
405 mask <<= 1;
406 p *= p;
407 }
408 return r;
409}
410
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000411static PyObject *
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000412float_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000413 PyFloatObject *v;
414 PyObject *w;
415 PyFloatObject *z;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000416{
417 double iv, iw, ix;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000418 long intw;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000419 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
420 * The z parameter is really only going to be useful for integers and
421 * long integers. Maybe something clever with logarithms could be done.
422 * [AMK]
423 */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000424 iv = v->ob_fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000425 iw = ((PyFloatObject *)w)->ob_fval;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000426 intw = (long)iw;
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000427 if (iw == intw && -10000 < intw && intw < 10000) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000428 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum86c04c21996-08-09 20:50:14 +0000429 if (intw == 0) { /* x**0 is 1, even 0**0 */
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000430 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431 if ((PyObject *)z!=Py_None) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000432 ix=fmod(1.0, z->ob_fval);
433 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
434 }
435 else ix=1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000436 PyFPE_END_PROTECT(ix)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437 return PyFloat_FromDouble(ix);
Guido van Rossum70d93461991-05-28 21:57:39 +0000438 }
Guido van Rossum86c04c21996-08-09 20:50:14 +0000439 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000440 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000441 if (intw > 0)
442 ix = powu(iv, intw);
443 else
444 ix = 1./powu(iv, -intw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000445 PyFPE_END_PROTECT(ix)
Guido van Rossum86c04c21996-08-09 20:50:14 +0000446 }
447 else {
448 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000449 if (iv == 0.0) {
450 if (iw < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000451 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000452 "0.0 to a negative power");
Guido van Rossum39739ea1996-01-12 01:22:56 +0000453 return NULL;
454 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000455 return PyFloat_FromDouble(0.0);
Guido van Rossum39739ea1996-01-12 01:22:56 +0000456 }
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000457 if (iv < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000459 "negative number to a float power");
460 return NULL;
461 }
Guido van Rossum39739ea1996-01-12 01:22:56 +0000462 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000463 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000464 ix = pow(iv, iw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000465 PyFPE_END_PROTECT(ix)
Guido van Rossum70d93461991-05-28 21:57:39 +0000466 }
Guido van Rossum7fa52f81991-12-16 15:43:14 +0000467 CHECK(ix);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000468 if (errno != 0) {
469 /* XXX could it be another type of error? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000470 PyErr_SetFromErrno(PyExc_OverflowError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471 return NULL;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000472 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000473 if ((PyObject *)z!=Py_None) {
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000474 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000475 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
476 if ( ix!=0 &&
477 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
478 ix+=z->ob_fval;
479 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000480 PyFPE_END_PROTECT(ix)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000481 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000482 return PyFloat_FromDouble(ix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483}
484
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486float_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000487 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000489 return PyFloat_FromDouble(-v->ob_fval);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490}
491
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000492static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000493float_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000496 Py_INCREF(v);
497 return (PyObject *)v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000498}
499
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000500static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000501float_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502 PyFloatObject *v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000503{
504 if (v->ob_fval < 0)
505 return float_neg(v);
506 else
507 return float_pos(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508}
509
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000510static int
511float_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000512 PyFloatObject *v;
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000513{
514 return v->ob_fval != 0.0;
515}
516
Guido van Rossum234f9421993-06-17 12:35:49 +0000517static int
Guido van Rossume6eefc21992-08-14 12:06:52 +0000518float_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000519 PyObject **pv;
520 PyObject **pw;
Guido van Rossume6eefc21992-08-14 12:06:52 +0000521{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000522 if (PyInt_Check(*pw)) {
523 long x = PyInt_AsLong(*pw);
524 *pw = PyFloat_FromDouble((double)x);
525 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000526 return 0;
527 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 else if (PyLong_Check(*pw)) {
529 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
530 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000531 return 0;
532 }
533 return 1; /* Can't do it */
534}
535
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000536static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000537float_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000538 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000539{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540 double x = PyFloat_AsDouble(v);
Guido van Rossum03093a21994-09-28 15:51:32 +0000541 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
542 : (x = floor(x)) > (double)LONG_MAX) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543 PyErr_SetString(PyExc_OverflowError,
544 "float too large to convert");
Guido van Rossum03093a21994-09-28 15:51:32 +0000545 return NULL;
546 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000547 return PyInt_FromLong((long)x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000548}
549
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000550static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000551float_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000553{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554 double x = PyFloat_AsDouble(v);
555 return PyLong_FromDouble(x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000556}
557
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000558static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000559float_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000560 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000561{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562 Py_INCREF(v);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000563 return v;
564}
565
566
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567static PyNumberMethods float_as_number = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000568 (binaryfunc)float_add, /*nb_add*/
569 (binaryfunc)float_sub, /*nb_subtract*/
570 (binaryfunc)float_mul, /*nb_multiply*/
571 (binaryfunc)float_div, /*nb_divide*/
572 (binaryfunc)float_rem, /*nb_remainder*/
573 (binaryfunc)float_divmod, /*nb_divmod*/
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000574 (ternaryfunc)float_pow, /*nb_power*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000575 (unaryfunc)float_neg, /*nb_negative*/
576 (unaryfunc)float_pos, /*nb_positive*/
577 (unaryfunc)float_abs, /*nb_absolute*/
578 (inquiry)float_nonzero, /*nb_nonzero*/
Guido van Rossum27acb331991-10-24 14:55:28 +0000579 0, /*nb_invert*/
580 0, /*nb_lshift*/
581 0, /*nb_rshift*/
582 0, /*nb_and*/
583 0, /*nb_xor*/
584 0, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000585 (coercion)float_coerce, /*nb_coerce*/
586 (unaryfunc)float_int, /*nb_int*/
587 (unaryfunc)float_long, /*nb_long*/
588 (unaryfunc)float_float, /*nb_float*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000589 0, /*nb_oct*/
590 0, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000591};
592
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000593PyTypeObject PyFloat_Type = {
594 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595 0,
596 "float",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000597 sizeof(PyFloatObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000598 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000599 (destructor)float_dealloc, /*tp_dealloc*/
600 (printfunc)float_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601 0, /*tp_getattr*/
602 0, /*tp_setattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000603 (cmpfunc)float_compare, /*tp_compare*/
604 (reprfunc)float_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000605 &float_as_number, /*tp_as_number*/
606 0, /*tp_as_sequence*/
607 0, /*tp_as_mapping*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000608 (hashfunc)float_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609};
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000610
611void
612PyFloat_Fini()
613{
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000614 PyFloatObject *p, *list;
615 int i;
616 int bc, bf; /* block count, number of freed blocks */
617 int frem, fsum; /* remaining unfreed floats per block, total */
618
619 bc = 0;
620 bf = 0;
621 fsum = 0;
622 list = block_list;
623 block_list = NULL;
624 while (list != NULL) {
625 p = list;
626 p = (PyFloatObject *)((char *)p + BHEAD_SIZE);
627 bc++;
628 frem = 0;
629 for (i = 0; i < N_FLOATOBJECTS; i++, p++) {
630 if (PyFloat_Check(p) && p->ob_refcnt != 0)
631 frem++;
632 }
633 p = list;
634 list = *(PyFloatObject **)p;
635 if (frem) {
636 *(PyFloatObject **)p = block_list;
637 block_list = p;
638 }
639 else {
640 PyMem_FREE(p);
641 bf++;
642 }
643 fsum += frem;
644 }
645 if (Py_VerboseFlag) {
646 fprintf(stderr, "# cleanup floats");
647 if (!fsum) {
648 fprintf(stderr, "\n");
649 }
650 else {
651 fprintf(stderr,
652 ": %d unfreed float%s in %d out of %d block%s\n",
653 fsum, fsum == 1 ? "" : "s",
654 bc - bf, bc, bc == 1 ? "" : "s");
655 }
656 }
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000657}