blob: ba373091295df1e720fe89fb1432bf650617c55f [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
Guido van Rossum234f9421993-06-17 12:35:49 +0000152static void
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000153float_dealloc(op)
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000154 PyFloatObject *op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000155{
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000156 op->ob_type = (struct _typeobject *)free_list;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000157 free_list = op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000158}
159
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160double
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000161PyFloat_AsDouble(op)
162 PyObject *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000164 PyNumberMethods *nb;
165 PyFloatObject *fo;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166 double val;
167
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000168 if (op && PyFloat_Check(op))
169 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170
171 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
172 nb->nb_float == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000173 PyErr_BadArgument();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 return -1;
175 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000176
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000177 fo = (PyFloatObject*) (*nb->nb_float) (op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178 if (fo == NULL)
179 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000180 if (!PyFloat_Check(fo)) {
181 PyErr_SetString(PyExc_TypeError,
182 "nb_float should return float object");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183 return -1;
184 }
185
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000186 val = PyFloat_AS_DOUBLE(fo);
187 Py_DECREF(fo);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
189 return val;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000190}
191
192/* Methods */
193
Guido van Rossum27dec7e1991-06-04 19:42:53 +0000194void
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000195PyFloat_AsString(buf, v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196 char *buf;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000197 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198{
199 register char *cp;
200 /* Subroutine for float_repr and float_print.
201 We want float numbers to be recognizable as such,
202 i.e., they should contain a decimal point or an exponent.
203 However, %g may print the number as an integer;
204 in such cases, we append ".0" to the string. */
205 sprintf(buf, "%.12g", v->ob_fval);
206 cp = buf;
207 if (*cp == '-')
208 cp++;
209 for (; *cp != '\0'; cp++) {
210 /* Any non-digit means it's not an integer;
211 this takes care of NAN and INF as well. */
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000212 if (!isdigit(Py_CHARMASK(*cp)))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 break;
214 }
215 if (*cp == '\0') {
216 *cp++ = '.';
217 *cp++ = '0';
218 *cp++ = '\0';
219 }
220}
221
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000222/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000223static int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224float_print(v, fp, flags)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 FILE *fp;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000227 int flags; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228{
229 char buf[100];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000230 PyFloat_AsString(buf, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 fputs(buf, fp);
Guido van Rossum90933611991-06-07 16:10:43 +0000232 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233}
234
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000235static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236float_repr(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000237 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238{
239 char buf[100];
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000240 PyFloat_AsString(buf, v);
241 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242}
243
244static int
245float_compare(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000246 PyFloatObject *v, *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247{
248 double i = v->ob_fval;
249 double j = w->ob_fval;
250 return (i < j) ? -1 : (i > j) ? 1 : 0;
251}
252
Guido van Rossum9bfef441993-03-29 10:43:31 +0000253static long
254float_hash(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000255 PyFloatObject *v;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000256{
257 double intpart, fractpart;
258 int expo;
259 long x;
260 /* This is designed so that Python numbers with the same
261 value hash to the same value, otherwise comparisons
262 of mapping keys will turn out weird */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
265{
266 extended e;
267 fractpart = modf(v->ob_fval, &e);
268 intpart = e;
269}
270#else
Guido van Rossum9bfef441993-03-29 10:43:31 +0000271 fractpart = modf(v->ob_fval, &intpart);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#endif
273
Guido van Rossum9bfef441993-03-29 10:43:31 +0000274 if (fractpart == 0.0) {
275 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
276 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000277 PyObject *w = PyLong_FromDouble(v->ob_fval);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000278 if (w == NULL)
279 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000280 x = PyObject_Hash(w);
281 Py_DECREF(w);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000282 return x;
283 }
284 x = (long)intpart;
285 }
286 else {
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000287 /* Note -- if you change this code, also change the copy
288 in complexobject.c */
289 long hipart;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000290 fractpart = frexp(fractpart, &expo);
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000291 fractpart = fractpart * 2147483648.0; /* 2**31 */
292 hipart = (long)fractpart; /* Take the top 32 bits */
293 fractpart = (fractpart - (double)hipart) * 2147483648.0;
294 /* Get the next 32 bits */
295 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
296 /* Combine everything */
Guido van Rossum9bfef441993-03-29 10:43:31 +0000297 }
298 if (x == -1)
299 x = -2;
300 return x;
301}
302
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000303static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304float_add(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000305 PyFloatObject *v;
306 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000308 double result;
309 PyFPE_START_PROTECT("add", return 0)
310 result = v->ob_fval + w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000311 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000312 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313}
314
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316float_sub(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000317 PyFloatObject *v;
318 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000320 double result;
321 PyFPE_START_PROTECT("subtract", return 0)
322 result = v->ob_fval - w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000323 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000324 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325}
326
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000327static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328float_mul(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000329 PyFloatObject *v;
330 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000332 double result;
333
334 PyFPE_START_PROTECT("multiply", return 0)
335 result = v->ob_fval * w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000336 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000337 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338}
339
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000340static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341float_div(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000342 PyFloatObject *v;
343 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000345 double result;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000346 if (w->ob_fval == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000347 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348 return NULL;
349 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000350 PyFPE_START_PROTECT("divide", return 0)
351 result = v->ob_fval / w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000352 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000353 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354}
355
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000356static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357float_rem(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000358 PyFloatObject *v;
359 PyFloatObject *w;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360{
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000361 double vx, wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000362 double mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000363 wx = w->ob_fval;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000365 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000366 return NULL;
367 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000368 PyFPE_START_PROTECT("modulo", return 0)
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000369 vx = v->ob_fval;
370 mod = fmod(vx, wx);
Guido van Rossum9263e781999-05-06 14:26:34 +0000371 /* note: checking mod*wx < 0 is incorrect -- underflows to
372 0 if wx < sqrt(smallest nonzero double) */
373 if (mod && ((wx < 0) != (mod < 0))) {
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000374 mod += wx;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000375 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000376 PyFPE_END_PROTECT(mod)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000377 return PyFloat_FromDouble(mod);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378}
379
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000381float_divmod(v, w)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000382 PyFloatObject *v;
383 PyFloatObject *w;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000384{
Guido van Rossum15ecff41991-10-20 20:16:45 +0000385 double vx, wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000386 double div, mod, floordiv;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000387 wx = w->ob_fval;
Guido van Rossum15ecff41991-10-20 20:16:45 +0000388 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000389 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
Guido van Rossum15ecff41991-10-20 20:16:45 +0000390 return NULL;
391 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000392 PyFPE_START_PROTECT("divmod", return 0)
Guido van Rossum15ecff41991-10-20 20:16:45 +0000393 vx = v->ob_fval;
394 mod = fmod(vx, wx);
Guido van Rossum9263e781999-05-06 14:26:34 +0000395 /* fmod is typically exact, so vx-mod is *mathemtically* an
396 exact multiple of wx. But this is fp arithmetic, and fp
397 vx - mod is an approximation; the result is that div may
398 not be an exact integral value after the division, although
399 it will always be very close to one.
400 */
Guido van Rossum15ecff41991-10-20 20:16:45 +0000401 div = (vx - mod) / wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000402 /* note: checking mod*wx < 0 is incorrect -- underflows to
403 0 if wx < sqrt(smallest nonzero double) */
404 if (mod && ((wx < 0) != (mod < 0))) {
Guido van Rossum15ecff41991-10-20 20:16:45 +0000405 mod += wx;
406 div -= 1.0;
407 }
Guido van Rossum9263e781999-05-06 14:26:34 +0000408 /* snap quotient to nearest integral value */
409 floordiv = floor(div);
410 if (div - floordiv > 0.5)
411 floordiv += 1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000412 PyFPE_END_PROTECT(div)
Guido van Rossum9263e781999-05-06 14:26:34 +0000413 return Py_BuildValue("(dd)", floordiv, mod);
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000414}
415
Guido van Rossum363078a1996-05-24 20:45:01 +0000416static double powu(x, n)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000417 double x;
418 long n;
419{
420 double r = 1.;
421 double p = x;
422 long mask = 1;
423 while (mask > 0 && n >= mask) {
424 if (n & mask)
425 r *= p;
426 mask <<= 1;
427 p *= p;
428 }
429 return r;
430}
431
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000432static PyObject *
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000433float_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 PyFloatObject *v;
435 PyObject *w;
436 PyFloatObject *z;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000437{
438 double iv, iw, ix;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000439 long intw;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000440 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
441 * The z parameter is really only going to be useful for integers and
442 * long integers. Maybe something clever with logarithms could be done.
443 * [AMK]
444 */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000445 iv = v->ob_fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000446 iw = ((PyFloatObject *)w)->ob_fval;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000447 intw = (long)iw;
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000448 if (iw == intw && -10000 < intw && intw < 10000) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000449 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum86c04c21996-08-09 20:50:14 +0000450 if (intw == 0) { /* x**0 is 1, even 0**0 */
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000451 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000452 if ((PyObject *)z!=Py_None) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000453 ix=fmod(1.0, z->ob_fval);
454 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
455 }
456 else ix=1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000457 PyFPE_END_PROTECT(ix)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000458 return PyFloat_FromDouble(ix);
Guido van Rossum70d93461991-05-28 21:57:39 +0000459 }
Guido van Rossum86c04c21996-08-09 20:50:14 +0000460 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000461 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000462 if (intw > 0)
463 ix = powu(iv, intw);
464 else
465 ix = 1./powu(iv, -intw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000466 PyFPE_END_PROTECT(ix)
Guido van Rossum86c04c21996-08-09 20:50:14 +0000467 }
468 else {
469 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000470 if (iv == 0.0) {
471 if (iw < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000472 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000473 "0.0 to a negative power");
Guido van Rossum39739ea1996-01-12 01:22:56 +0000474 return NULL;
475 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000476 return PyFloat_FromDouble(0.0);
Guido van Rossum39739ea1996-01-12 01:22:56 +0000477 }
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000478 if (iv < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000479 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000480 "negative number to a float power");
481 return NULL;
482 }
Guido van Rossum39739ea1996-01-12 01:22:56 +0000483 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000484 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000485 ix = pow(iv, iw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000486 PyFPE_END_PROTECT(ix)
Guido van Rossum70d93461991-05-28 21:57:39 +0000487 }
Guido van Rossum7fa52f81991-12-16 15:43:14 +0000488 CHECK(ix);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000489 if (errno != 0) {
490 /* XXX could it be another type of error? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000491 PyErr_SetFromErrno(PyExc_OverflowError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492 return NULL;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000493 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494 if ((PyObject *)z!=Py_None) {
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000495 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000496 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
497 if ( ix!=0 &&
498 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
499 ix+=z->ob_fval;
500 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000501 PyFPE_END_PROTECT(ix)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000502 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 return PyFloat_FromDouble(ix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000504}
505
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000506static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507float_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000510 return PyFloat_FromDouble(-v->ob_fval);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511}
512
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000513static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514float_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000515 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000517 Py_INCREF(v);
518 return (PyObject *)v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000519}
520
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000522float_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000523 PyFloatObject *v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000524{
525 if (v->ob_fval < 0)
526 return float_neg(v);
527 else
528 return float_pos(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529}
530
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000531static int
532float_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000533 PyFloatObject *v;
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000534{
535 return v->ob_fval != 0.0;
536}
537
Guido van Rossum234f9421993-06-17 12:35:49 +0000538static int
Guido van Rossume6eefc21992-08-14 12:06:52 +0000539float_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000540 PyObject **pv;
541 PyObject **pw;
Guido van Rossume6eefc21992-08-14 12:06:52 +0000542{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000543 if (PyInt_Check(*pw)) {
544 long x = PyInt_AsLong(*pw);
545 *pw = PyFloat_FromDouble((double)x);
546 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000547 return 0;
548 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000549 else if (PyLong_Check(*pw)) {
550 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
551 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000552 return 0;
553 }
554 return 1; /* Can't do it */
555}
556
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000557static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000558float_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000560{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 double x = PyFloat_AsDouble(v);
Guido van Rossum03093a21994-09-28 15:51:32 +0000562 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
563 : (x = floor(x)) > (double)LONG_MAX) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000564 PyErr_SetString(PyExc_OverflowError,
565 "float too large to convert");
Guido van Rossum03093a21994-09-28 15:51:32 +0000566 return NULL;
567 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000568 return PyInt_FromLong((long)x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000569}
570
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000572float_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000573 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000574{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000575 double x = PyFloat_AsDouble(v);
576 return PyLong_FromDouble(x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000577}
578
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000579static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000580float_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000581 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000582{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000583 Py_INCREF(v);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000584 return v;
585}
586
587
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000588static PyNumberMethods float_as_number = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000589 (binaryfunc)float_add, /*nb_add*/
590 (binaryfunc)float_sub, /*nb_subtract*/
591 (binaryfunc)float_mul, /*nb_multiply*/
592 (binaryfunc)float_div, /*nb_divide*/
593 (binaryfunc)float_rem, /*nb_remainder*/
594 (binaryfunc)float_divmod, /*nb_divmod*/
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000595 (ternaryfunc)float_pow, /*nb_power*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000596 (unaryfunc)float_neg, /*nb_negative*/
597 (unaryfunc)float_pos, /*nb_positive*/
598 (unaryfunc)float_abs, /*nb_absolute*/
599 (inquiry)float_nonzero, /*nb_nonzero*/
Guido van Rossum27acb331991-10-24 14:55:28 +0000600 0, /*nb_invert*/
601 0, /*nb_lshift*/
602 0, /*nb_rshift*/
603 0, /*nb_and*/
604 0, /*nb_xor*/
605 0, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000606 (coercion)float_coerce, /*nb_coerce*/
607 (unaryfunc)float_int, /*nb_int*/
608 (unaryfunc)float_long, /*nb_long*/
609 (unaryfunc)float_float, /*nb_float*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000610 0, /*nb_oct*/
611 0, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612};
613
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614PyTypeObject PyFloat_Type = {
615 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000616 0,
617 "float",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000618 sizeof(PyFloatObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000620 (destructor)float_dealloc, /*tp_dealloc*/
621 (printfunc)float_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000622 0, /*tp_getattr*/
623 0, /*tp_setattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000624 (cmpfunc)float_compare, /*tp_compare*/
625 (reprfunc)float_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000626 &float_as_number, /*tp_as_number*/
627 0, /*tp_as_sequence*/
628 0, /*tp_as_mapping*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000629 (hashfunc)float_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000630};
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000631
632void
633PyFloat_Fini()
634{
Guido van Rossum3fce8831999-03-12 19:43:17 +0000635 PyFloatObject *p;
636 PyFloatBlock *list, *next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000637 int i;
638 int bc, bf; /* block count, number of freed blocks */
639 int frem, fsum; /* remaining unfreed floats per block, total */
640
641 bc = 0;
642 bf = 0;
643 fsum = 0;
644 list = block_list;
645 block_list = NULL;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000646 free_list = NULL;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000647 while (list != NULL) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000648 bc++;
649 frem = 0;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000650 for (i = 0, p = &list->objects[0];
651 i < N_FLOATOBJECTS;
652 i++, p++) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000653 if (PyFloat_Check(p) && p->ob_refcnt != 0)
654 frem++;
655 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000656 next = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000657 if (frem) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000658 list->next = block_list;
659 block_list = list;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000660 for (i = 0, p = &list->objects[0];
661 i < N_FLOATOBJECTS;
662 i++, p++) {
663 if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
664 p->ob_type = (struct _typeobject *)
665 free_list;
666 free_list = p;
667 }
668 }
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000669 }
670 else {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000671 PyMem_FREE(list);
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000672 bf++;
673 }
674 fsum += frem;
Guido van Rossum3fce8831999-03-12 19:43:17 +0000675 list = next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000676 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000677 if (!Py_VerboseFlag)
678 return;
679 fprintf(stderr, "# cleanup floats");
680 if (!fsum) {
681 fprintf(stderr, "\n");
682 }
683 else {
684 fprintf(stderr,
685 ": %d unfreed float%s in %d out of %d block%s\n",
686 fsum, fsum == 1 ? "" : "s",
687 bc - bf, bc, bc == 1 ? "" : "s");
688 }
689 if (Py_VerboseFlag > 1) {
690 list = block_list;
691 while (list != NULL) {
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000692 for (i = 0, p = &list->objects[0];
693 i < N_FLOATOBJECTS;
694 i++, p++) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000695 if (PyFloat_Check(p) && p->ob_refcnt != 0) {
696 char buf[100];
697 PyFloat_AsString(buf, p);
698 fprintf(stderr,
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000699 "# <float at %lx, refcnt=%d, val=%s>\n",
Guido van Rossum3fce8831999-03-12 19:43:17 +0000700 p, p->ob_refcnt, buf);
701 }
702 }
703 list = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000704 }
705 }
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000706}