blob: cb5d9e36eddec7907afd82a4a896a48fd8f2c402 [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. */
Guido van Rossum93ad0df1997-05-13 21:00:42 +000097#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
Guido van Rossum3fce8831999-03-12 19:43:17 +000098#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
Guido van Rossumf61bbc81999-03-12 00:12:21 +000099#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
Guido van Rossum3fce8831999-03-12 19:43:17 +0000100
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000101#define PyMem_MALLOC malloc
102#define PyMem_FREE free
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000103
Guido van Rossum3fce8831999-03-12 19:43:17 +0000104struct _floatblock {
105 struct _floatblock *next;
106 PyFloatObject objects[N_FLOATOBJECTS];
107};
108
109typedef struct _floatblock PyFloatBlock;
110
111static PyFloatBlock *block_list = NULL;
112static PyFloatObject *free_list = NULL;
113
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000114static PyFloatObject *
115fill_free_list()
116{
117 PyFloatObject *p, *q;
Guido van Rossum3fce8831999-03-12 19:43:17 +0000118 p = (PyFloatObject *)PyMem_MALLOC(sizeof(PyFloatBlock));
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000119 if (p == NULL)
120 return (PyFloatObject *)PyErr_NoMemory();
Guido van Rossum3fce8831999-03-12 19:43:17 +0000121 ((PyFloatBlock *)p)->next = block_list;
122 block_list = (PyFloatBlock *)p;
123 p = &((PyFloatBlock *)p)->objects[0];
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000124 q = p + N_FLOATOBJECTS;
125 while (--q > p)
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000126 q->ob_type = (struct _typeobject *)(q-1);
127 q->ob_type = NULL;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000128 return p + N_FLOATOBJECTS - 1;
129}
130
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000131PyObject *
Guido van Rossum07e3a7e1995-02-27 10:13:37 +0000132#ifdef __SC__
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000133PyFloat_FromDouble(double fval)
Guido van Rossum07e3a7e1995-02-27 10:13:37 +0000134#else
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000135PyFloat_FromDouble(fval)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 double fval;
Guido van Rossum07e3a7e1995-02-27 10:13:37 +0000137#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138{
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000139 register PyFloatObject *op;
140 if (free_list == NULL) {
141 if ((free_list = fill_free_list()) == NULL)
142 return NULL;
143 }
144 op = free_list;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000145 free_list = (PyFloatObject *)op->ob_type;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000146 op->ob_type = &PyFloat_Type;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000147 op->ob_fval = fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000148 _Py_NewReference(op);
149 return (PyObject *) op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150}
151
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000152PyObject *
153PyFloat_FromString(v, pend)
154 PyObject *v;
155 char **pend;
156{
157 extern double strtod Py_PROTO((const char *, char **));
158 char *s, *last, *end;
159 double x;
160 char buffer[256]; /* For errors */
161
162 if (!PyString_Check(v))
163 return NULL;
164 s = PyString_AS_STRING(v);
165
166 last = s + PyString_GET_SIZE(v);
167 while (*s && isspace(Py_CHARMASK(*s)))
168 s++;
169 if (s[0] == '\0') {
170 PyErr_SetString(PyExc_ValueError, "empty string for float()");
171 return NULL;
172 }
173 errno = 0;
174 PyFPE_START_PROTECT("PyFloat_FromString", return 0)
175 x = strtod(s, &end);
176 PyFPE_END_PROTECT(x)
177 /* Believe it or not, Solaris 2.6 can move end *beyond* the null
178 byte at the end of the string, when the input is inf(inity) */
179 if (end > last)
180 end = last;
181 while (*end && isspace(Py_CHARMASK(*end)))
182 end++;
183 if (*end != '\0') {
184 sprintf(buffer, "invalid literal for float(): %.200s", s);
185 PyErr_SetString(PyExc_ValueError, buffer);
186 return NULL;
187 }
188 else if (end != PyString_AS_STRING(v) + PyString_GET_SIZE(v)) {
189 PyErr_SetString(PyExc_ValueError,
190 "null byte in argument for float()");
191 return NULL;
192 }
193 else if (errno != 0) {
194 sprintf(buffer, "float() literal too large: %.200s", s);
195 PyErr_SetString(PyExc_ValueError, buffer);
196 return NULL;
197 }
198 if (pend)
199 *pend = end;
200 return PyFloat_FromDouble(x);
201}
202
Guido van Rossum234f9421993-06-17 12:35:49 +0000203static void
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000204float_dealloc(op)
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000205 PyFloatObject *op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000206{
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000207 op->ob_type = (struct _typeobject *)free_list;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000208 free_list = op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000209}
210
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211double
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212PyFloat_AsDouble(op)
213 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000215 PyNumberMethods *nb;
216 PyFloatObject *fo;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217 double val;
218
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000219 if (op && PyFloat_Check(op))
220 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
222 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
223 nb->nb_float == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000224 PyErr_BadArgument();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 return -1;
226 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 fo = (PyFloatObject*) (*nb->nb_float) (op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229 if (fo == NULL)
230 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000231 if (!PyFloat_Check(fo)) {
232 PyErr_SetString(PyExc_TypeError,
233 "nb_float should return float object");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234 return -1;
235 }
236
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 val = PyFloat_AS_DOUBLE(fo);
238 Py_DECREF(fo);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
240 return val;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241}
242
243/* Methods */
244
Guido van Rossum27dec7e1991-06-04 19:42:53 +0000245void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246PyFloat_AsString(buf, v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000248 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000249{
250 register char *cp;
251 /* Subroutine for float_repr and float_print.
252 We want float numbers to be recognizable as such,
253 i.e., they should contain a decimal point or an exponent.
254 However, %g may print the number as an integer;
255 in such cases, we append ".0" to the string. */
256 sprintf(buf, "%.12g", v->ob_fval);
257 cp = buf;
258 if (*cp == '-')
259 cp++;
260 for (; *cp != '\0'; cp++) {
261 /* Any non-digit means it's not an integer;
262 this takes care of NAN and INF as well. */
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000263 if (!isdigit(Py_CHARMASK(*cp)))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264 break;
265 }
266 if (*cp == '\0') {
267 *cp++ = '.';
268 *cp++ = '0';
269 *cp++ = '\0';
270 }
271}
272
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000273/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000274static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275float_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000276 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277 FILE *fp;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000278 int flags; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279{
280 char buf[100];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000281 PyFloat_AsString(buf, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282 fputs(buf, fp);
Guido van Rossum90933611991-06-07 16:10:43 +0000283 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284}
285
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000286static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287float_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000288 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289{
290 char buf[100];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000291 PyFloat_AsString(buf, v);
292 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293}
294
295static int
296float_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000297 PyFloatObject *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298{
299 double i = v->ob_fval;
300 double j = w->ob_fval;
301 return (i < j) ? -1 : (i > j) ? 1 : 0;
302}
303
Guido van Rossum9bfef441993-03-29 10:43:31 +0000304static long
305float_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000306 PyFloatObject *v;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000307{
308 double intpart, fractpart;
309 int expo;
310 long x;
311 /* This is designed so that Python numbers with the same
312 value hash to the same value, otherwise comparisons
313 of mapping keys will turn out weird */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000314
315#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
316{
317 extended e;
318 fractpart = modf(v->ob_fval, &e);
319 intpart = e;
320}
321#else
Guido van Rossum9bfef441993-03-29 10:43:31 +0000322 fractpart = modf(v->ob_fval, &intpart);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000323#endif
324
Guido van Rossum9bfef441993-03-29 10:43:31 +0000325 if (fractpart == 0.0) {
326 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
327 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000328 PyObject *w = PyLong_FromDouble(v->ob_fval);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000329 if (w == NULL)
330 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000331 x = PyObject_Hash(w);
332 Py_DECREF(w);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000333 return x;
334 }
335 x = (long)intpart;
336 }
337 else {
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000338 /* Note -- if you change this code, also change the copy
339 in complexobject.c */
340 long hipart;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000341 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000342 fractpart = fractpart * 2147483648.0; /* 2**31 */
343 hipart = (long)fractpart; /* Take the top 32 bits */
344 fractpart = (fractpart - (double)hipart) * 2147483648.0;
345 /* Get the next 32 bits */
346 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
347 /* Combine everything */
Guido van Rossum9bfef441993-03-29 10:43:31 +0000348 }
349 if (x == -1)
350 x = -2;
351 return x;
352}
353
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000354static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355float_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356 PyFloatObject *v;
357 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000358{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000359 double result;
360 PyFPE_START_PROTECT("add", return 0)
361 result = v->ob_fval + w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000362 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000363 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364}
365
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000366static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367float_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000368 PyFloatObject *v;
369 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000371 double result;
372 PyFPE_START_PROTECT("subtract", return 0)
373 result = v->ob_fval - w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000374 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000375 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376}
377
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000378static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379float_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380 PyFloatObject *v;
381 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000382{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000383 double result;
384
385 PyFPE_START_PROTECT("multiply", return 0)
386 result = v->ob_fval * w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000387 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000388 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389}
390
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000391static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392float_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000393 PyFloatObject *v;
394 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000396 double result;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000397 if (w->ob_fval == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399 return NULL;
400 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000401 PyFPE_START_PROTECT("divide", return 0)
402 result = v->ob_fval / w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000403 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000404 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405}
406
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000407static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000408float_rem(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000409 PyFloatObject *v;
410 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000411{
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000412 double vx, wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000413 double mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000414 wx = w->ob_fval;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000415 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000416 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417 return NULL;
418 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000419 PyFPE_START_PROTECT("modulo", return 0)
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000420 vx = v->ob_fval;
421 mod = fmod(vx, wx);
Guido van Rossum9263e781999-05-06 14:26:34 +0000422 /* note: checking mod*wx < 0 is incorrect -- underflows to
423 0 if wx < sqrt(smallest nonzero double) */
424 if (mod && ((wx < 0) != (mod < 0))) {
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000425 mod += wx;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000426 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000427 PyFPE_END_PROTECT(mod)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000428 return PyFloat_FromDouble(mod);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000429}
430
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000431static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000432float_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000433 PyFloatObject *v;
434 PyFloatObject *w;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000435{
Guido van Rossum15ecff41991-10-20 20:16:45 +0000436 double vx, wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000437 double div, mod, floordiv;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000438 wx = w->ob_fval;
Guido van Rossum15ecff41991-10-20 20:16:45 +0000439 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000440 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
Guido van Rossum15ecff41991-10-20 20:16:45 +0000441 return NULL;
442 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000443 PyFPE_START_PROTECT("divmod", return 0)
Guido van Rossum15ecff41991-10-20 20:16:45 +0000444 vx = v->ob_fval;
445 mod = fmod(vx, wx);
Guido van Rossum9263e781999-05-06 14:26:34 +0000446 /* fmod is typically exact, so vx-mod is *mathemtically* an
447 exact multiple of wx. But this is fp arithmetic, and fp
448 vx - mod is an approximation; the result is that div may
449 not be an exact integral value after the division, although
450 it will always be very close to one.
451 */
Guido van Rossum15ecff41991-10-20 20:16:45 +0000452 div = (vx - mod) / wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000453 /* note: checking mod*wx < 0 is incorrect -- underflows to
454 0 if wx < sqrt(smallest nonzero double) */
455 if (mod && ((wx < 0) != (mod < 0))) {
Guido van Rossum15ecff41991-10-20 20:16:45 +0000456 mod += wx;
457 div -= 1.0;
458 }
Guido van Rossum9263e781999-05-06 14:26:34 +0000459 /* snap quotient to nearest integral value */
460 floordiv = floor(div);
461 if (div - floordiv > 0.5)
462 floordiv += 1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000463 PyFPE_END_PROTECT(div)
Guido van Rossum9263e781999-05-06 14:26:34 +0000464 return Py_BuildValue("(dd)", floordiv, mod);
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000465}
466
Guido van Rossum363078a1996-05-24 20:45:01 +0000467static double powu(x, n)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000468 double x;
469 long n;
470{
471 double r = 1.;
472 double p = x;
473 long mask = 1;
474 while (mask > 0 && n >= mask) {
475 if (n & mask)
476 r *= p;
477 mask <<= 1;
478 p *= p;
479 }
480 return r;
481}
482
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000483static PyObject *
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000484float_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485 PyFloatObject *v;
486 PyObject *w;
487 PyFloatObject *z;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488{
489 double iv, iw, ix;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000490 long intw;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000491 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
492 * The z parameter is really only going to be useful for integers and
493 * long integers. Maybe something clever with logarithms could be done.
494 * [AMK]
495 */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000496 iv = v->ob_fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000497 iw = ((PyFloatObject *)w)->ob_fval;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000498 intw = (long)iw;
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000499 if (iw == intw && -10000 < intw && intw < 10000) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000500 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum86c04c21996-08-09 20:50:14 +0000501 if (intw == 0) { /* x**0 is 1, even 0**0 */
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000502 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 if ((PyObject *)z!=Py_None) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000504 ix=fmod(1.0, z->ob_fval);
505 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
506 }
507 else ix=1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000508 PyFPE_END_PROTECT(ix)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000509 return PyFloat_FromDouble(ix);
Guido van Rossum70d93461991-05-28 21:57:39 +0000510 }
Guido van Rossum86c04c21996-08-09 20:50:14 +0000511 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000512 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000513 if (intw > 0)
514 ix = powu(iv, intw);
515 else
516 ix = 1./powu(iv, -intw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000517 PyFPE_END_PROTECT(ix)
Guido van Rossum86c04c21996-08-09 20:50:14 +0000518 }
519 else {
520 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000521 if (iv == 0.0) {
522 if (iw < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000524 "0.0 to a negative power");
Guido van Rossum39739ea1996-01-12 01:22:56 +0000525 return NULL;
526 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000527 return PyFloat_FromDouble(0.0);
Guido van Rossum39739ea1996-01-12 01:22:56 +0000528 }
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000529 if (iv < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000530 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000531 "negative number to a float power");
532 return NULL;
533 }
Guido van Rossum39739ea1996-01-12 01:22:56 +0000534 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000535 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000536 ix = pow(iv, iw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000537 PyFPE_END_PROTECT(ix)
Guido van Rossum70d93461991-05-28 21:57:39 +0000538 }
Guido van Rossum7fa52f81991-12-16 15:43:14 +0000539 CHECK(ix);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000540 if (errno != 0) {
541 /* XXX could it be another type of error? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000542 PyErr_SetFromErrno(PyExc_OverflowError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000543 return NULL;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000544 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000545 if ((PyObject *)z!=Py_None) {
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000546 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000547 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
548 if ( ix!=0 &&
549 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
550 ix+=z->ob_fval;
551 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000552 PyFPE_END_PROTECT(ix)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000553 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000554 return PyFloat_FromDouble(ix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000555}
556
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000558float_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 return PyFloat_FromDouble(-v->ob_fval);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562}
563
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000564static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565float_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000566 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000567{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 Py_INCREF(v);
569 return (PyObject *)v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000570}
571
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000572static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000573float_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000574 PyFloatObject *v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000575{
576 if (v->ob_fval < 0)
577 return float_neg(v);
578 else
579 return float_pos(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000580}
581
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000582static int
583float_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000584 PyFloatObject *v;
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000585{
586 return v->ob_fval != 0.0;
587}
588
Guido van Rossum234f9421993-06-17 12:35:49 +0000589static int
Guido van Rossume6eefc21992-08-14 12:06:52 +0000590float_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000591 PyObject **pv;
592 PyObject **pw;
Guido van Rossume6eefc21992-08-14 12:06:52 +0000593{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000594 if (PyInt_Check(*pw)) {
595 long x = PyInt_AsLong(*pw);
596 *pw = PyFloat_FromDouble((double)x);
597 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000598 return 0;
599 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000600 else if (PyLong_Check(*pw)) {
601 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
602 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000603 return 0;
604 }
605 return 1; /* Can't do it */
606}
607
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000608static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000609float_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000610 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000611{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000612 double x = PyFloat_AsDouble(v);
Guido van Rossum03093a21994-09-28 15:51:32 +0000613 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
614 : (x = floor(x)) > (double)LONG_MAX) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000615 PyErr_SetString(PyExc_OverflowError,
616 "float too large to convert");
Guido van Rossum03093a21994-09-28 15:51:32 +0000617 return NULL;
618 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000619 return PyInt_FromLong((long)x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000620}
621
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000622static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000623float_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000624 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000625{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000626 double x = PyFloat_AsDouble(v);
627 return PyLong_FromDouble(x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000628}
629
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000630static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000631float_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000632 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000633{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000634 Py_INCREF(v);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000635 return v;
636}
637
638
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000639static PyNumberMethods float_as_number = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000640 (binaryfunc)float_add, /*nb_add*/
641 (binaryfunc)float_sub, /*nb_subtract*/
642 (binaryfunc)float_mul, /*nb_multiply*/
643 (binaryfunc)float_div, /*nb_divide*/
644 (binaryfunc)float_rem, /*nb_remainder*/
645 (binaryfunc)float_divmod, /*nb_divmod*/
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000646 (ternaryfunc)float_pow, /*nb_power*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000647 (unaryfunc)float_neg, /*nb_negative*/
648 (unaryfunc)float_pos, /*nb_positive*/
649 (unaryfunc)float_abs, /*nb_absolute*/
650 (inquiry)float_nonzero, /*nb_nonzero*/
Guido van Rossum27acb331991-10-24 14:55:28 +0000651 0, /*nb_invert*/
652 0, /*nb_lshift*/
653 0, /*nb_rshift*/
654 0, /*nb_and*/
655 0, /*nb_xor*/
656 0, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000657 (coercion)float_coerce, /*nb_coerce*/
658 (unaryfunc)float_int, /*nb_int*/
659 (unaryfunc)float_long, /*nb_long*/
660 (unaryfunc)float_float, /*nb_float*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000661 0, /*nb_oct*/
662 0, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000663};
664
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000665PyTypeObject PyFloat_Type = {
666 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667 0,
668 "float",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000669 sizeof(PyFloatObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000670 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000671 (destructor)float_dealloc, /*tp_dealloc*/
672 (printfunc)float_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000673 0, /*tp_getattr*/
674 0, /*tp_setattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000675 (cmpfunc)float_compare, /*tp_compare*/
676 (reprfunc)float_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000677 &float_as_number, /*tp_as_number*/
678 0, /*tp_as_sequence*/
679 0, /*tp_as_mapping*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000680 (hashfunc)float_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681};
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000682
683void
684PyFloat_Fini()
685{
Guido van Rossum3fce8831999-03-12 19:43:17 +0000686 PyFloatObject *p;
687 PyFloatBlock *list, *next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000688 int i;
689 int bc, bf; /* block count, number of freed blocks */
690 int frem, fsum; /* remaining unfreed floats per block, total */
691
692 bc = 0;
693 bf = 0;
694 fsum = 0;
695 list = block_list;
696 block_list = NULL;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000697 free_list = NULL;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000698 while (list != NULL) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000699 bc++;
700 frem = 0;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000701 for (i = 0, p = &list->objects[0];
702 i < N_FLOATOBJECTS;
703 i++, p++) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000704 if (PyFloat_Check(p) && p->ob_refcnt != 0)
705 frem++;
706 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000707 next = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000708 if (frem) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000709 list->next = block_list;
710 block_list = list;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000711 for (i = 0, p = &list->objects[0];
712 i < N_FLOATOBJECTS;
713 i++, p++) {
714 if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
715 p->ob_type = (struct _typeobject *)
716 free_list;
717 free_list = p;
718 }
719 }
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000720 }
721 else {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000722 PyMem_FREE(list);
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000723 bf++;
724 }
725 fsum += frem;
Guido van Rossum3fce8831999-03-12 19:43:17 +0000726 list = next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000727 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000728 if (!Py_VerboseFlag)
729 return;
730 fprintf(stderr, "# cleanup floats");
731 if (!fsum) {
732 fprintf(stderr, "\n");
733 }
734 else {
735 fprintf(stderr,
736 ": %d unfreed float%s in %d out of %d block%s\n",
737 fsum, fsum == 1 ? "" : "s",
738 bc - bf, bc, bc == 1 ? "" : "s");
739 }
740 if (Py_VerboseFlag > 1) {
741 list = block_list;
742 while (list != NULL) {
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000743 for (i = 0, p = &list->objects[0];
744 i < N_FLOATOBJECTS;
745 i++, p++) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000746 if (PyFloat_Check(p) && p->ob_refcnt != 0) {
747 char buf[100];
748 PyFloat_AsString(buf, p);
749 fprintf(stderr,
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000750 "# <float at %lx, refcnt=%d, val=%s>\n",
Guido van Rossum3fce8831999-03-12 19:43:17 +0000751 p, p->ob_refcnt, buf);
752 }
753 }
754 list = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000755 }
756 }
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000757}