blob: 120b561a598bf28b6b60a9e569be6a1624b0f3cf [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 Rossum3132a5a1992-03-27 17:28:44 +0000362 double /* div, */ 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 Rossum3132a5a1992-03-27 17:28:44 +0000371 /* div = (vx - mod) / wx; */
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000372 if (wx*mod < 0) {
373 mod += wx;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000374 /* div -= 1.0; */
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;
386 double div, mod;
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);
395 div = (vx - mod) / wx;
396 if (wx*mod < 0) {
397 mod += wx;
398 div -= 1.0;
399 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000400 PyFPE_END_PROTECT(div)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401 return Py_BuildValue("(dd)", div, mod);
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000402}
403
Guido van Rossum363078a1996-05-24 20:45:01 +0000404static double powu(x, n)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000405 double x;
406 long n;
407{
408 double r = 1.;
409 double p = x;
410 long mask = 1;
411 while (mask > 0 && n >= mask) {
412 if (n & mask)
413 r *= p;
414 mask <<= 1;
415 p *= p;
416 }
417 return r;
418}
419
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000420static PyObject *
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000421float_pow(v, w, z)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 PyFloatObject *v;
423 PyObject *w;
424 PyFloatObject *z;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000425{
426 double iv, iw, ix;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000427 long intw;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000428 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
429 * The z parameter is really only going to be useful for integers and
430 * long integers. Maybe something clever with logarithms could be done.
431 * [AMK]
432 */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000433 iv = v->ob_fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 iw = ((PyFloatObject *)w)->ob_fval;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000435 intw = (long)iw;
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000436 if (iw == intw && -10000 < intw && intw < 10000) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000437 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum86c04c21996-08-09 20:50:14 +0000438 if (intw == 0) { /* x**0 is 1, even 0**0 */
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000439 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000440 if ((PyObject *)z!=Py_None) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000441 ix=fmod(1.0, z->ob_fval);
442 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
443 }
444 else ix=1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000445 PyFPE_END_PROTECT(ix)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000446 return PyFloat_FromDouble(ix);
Guido van Rossum70d93461991-05-28 21:57:39 +0000447 }
Guido van Rossum86c04c21996-08-09 20:50:14 +0000448 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000449 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000450 if (intw > 0)
451 ix = powu(iv, intw);
452 else
453 ix = 1./powu(iv, -intw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000454 PyFPE_END_PROTECT(ix)
Guido van Rossum86c04c21996-08-09 20:50:14 +0000455 }
456 else {
457 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000458 if (iv == 0.0) {
459 if (iw < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000460 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000461 "0.0 to a negative power");
Guido van Rossum39739ea1996-01-12 01:22:56 +0000462 return NULL;
463 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000464 return PyFloat_FromDouble(0.0);
Guido van Rossum39739ea1996-01-12 01:22:56 +0000465 }
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000466 if (iv < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000467 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000468 "negative number to a float power");
469 return NULL;
470 }
Guido van Rossum39739ea1996-01-12 01:22:56 +0000471 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000472 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000473 ix = pow(iv, iw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000474 PyFPE_END_PROTECT(ix)
Guido van Rossum70d93461991-05-28 21:57:39 +0000475 }
Guido van Rossum7fa52f81991-12-16 15:43:14 +0000476 CHECK(ix);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000477 if (errno != 0) {
478 /* XXX could it be another type of error? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000479 PyErr_SetFromErrno(PyExc_OverflowError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480 return NULL;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000481 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000482 if ((PyObject *)z!=Py_None) {
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000483 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000484 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
485 if ( ix!=0 &&
486 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
487 ix+=z->ob_fval;
488 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000489 PyFPE_END_PROTECT(ix)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000490 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000491 return PyFloat_FromDouble(ix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492}
493
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000494static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495float_neg(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000496 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000498 return PyFloat_FromDouble(-v->ob_fval);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499}
500
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000501static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502float_pos(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000503 PyFloatObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000504{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000505 Py_INCREF(v);
506 return (PyObject *)v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000507}
508
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000509static PyObject *
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000510float_abs(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000511 PyFloatObject *v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000512{
513 if (v->ob_fval < 0)
514 return float_neg(v);
515 else
516 return float_pos(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517}
518
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000519static int
520float_nonzero(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000521 PyFloatObject *v;
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000522{
523 return v->ob_fval != 0.0;
524}
525
Guido van Rossum234f9421993-06-17 12:35:49 +0000526static int
Guido van Rossume6eefc21992-08-14 12:06:52 +0000527float_coerce(pv, pw)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000528 PyObject **pv;
529 PyObject **pw;
Guido van Rossume6eefc21992-08-14 12:06:52 +0000530{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000531 if (PyInt_Check(*pw)) {
532 long x = PyInt_AsLong(*pw);
533 *pw = PyFloat_FromDouble((double)x);
534 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000535 return 0;
536 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000537 else if (PyLong_Check(*pw)) {
538 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
539 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000540 return 0;
541 }
542 return 1; /* Can't do it */
543}
544
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000545static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000546float_int(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000547 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000548{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000549 double x = PyFloat_AsDouble(v);
Guido van Rossum03093a21994-09-28 15:51:32 +0000550 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
551 : (x = floor(x)) > (double)LONG_MAX) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000552 PyErr_SetString(PyExc_OverflowError,
553 "float too large to convert");
Guido van Rossum03093a21994-09-28 15:51:32 +0000554 return NULL;
555 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000556 return PyInt_FromLong((long)x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000557}
558
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000560float_long(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000561 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000562{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000563 double x = PyFloat_AsDouble(v);
564 return PyLong_FromDouble(x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000565}
566
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000567static PyObject *
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000568float_float(v)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569 PyObject *v;
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000570{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000571 Py_INCREF(v);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000572 return v;
573}
574
575
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000576static PyNumberMethods float_as_number = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000577 (binaryfunc)float_add, /*nb_add*/
578 (binaryfunc)float_sub, /*nb_subtract*/
579 (binaryfunc)float_mul, /*nb_multiply*/
580 (binaryfunc)float_div, /*nb_divide*/
581 (binaryfunc)float_rem, /*nb_remainder*/
582 (binaryfunc)float_divmod, /*nb_divmod*/
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000583 (ternaryfunc)float_pow, /*nb_power*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000584 (unaryfunc)float_neg, /*nb_negative*/
585 (unaryfunc)float_pos, /*nb_positive*/
586 (unaryfunc)float_abs, /*nb_absolute*/
587 (inquiry)float_nonzero, /*nb_nonzero*/
Guido van Rossum27acb331991-10-24 14:55:28 +0000588 0, /*nb_invert*/
589 0, /*nb_lshift*/
590 0, /*nb_rshift*/
591 0, /*nb_and*/
592 0, /*nb_xor*/
593 0, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000594 (coercion)float_coerce, /*nb_coerce*/
595 (unaryfunc)float_int, /*nb_int*/
596 (unaryfunc)float_long, /*nb_long*/
597 (unaryfunc)float_float, /*nb_float*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000598 0, /*nb_oct*/
599 0, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600};
601
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000602PyTypeObject PyFloat_Type = {
603 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604 0,
605 "float",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000606 sizeof(PyFloatObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000607 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000608 (destructor)float_dealloc, /*tp_dealloc*/
609 (printfunc)float_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000610 0, /*tp_getattr*/
611 0, /*tp_setattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000612 (cmpfunc)float_compare, /*tp_compare*/
613 (reprfunc)float_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614 &float_as_number, /*tp_as_number*/
615 0, /*tp_as_sequence*/
616 0, /*tp_as_mapping*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000617 (hashfunc)float_hash, /*tp_hash*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000618};
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000619
620void
621PyFloat_Fini()
622{
Guido van Rossum3fce8831999-03-12 19:43:17 +0000623 PyFloatObject *p;
624 PyFloatBlock *list, *next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000625 int i;
626 int bc, bf; /* block count, number of freed blocks */
627 int frem, fsum; /* remaining unfreed floats per block, total */
628
629 bc = 0;
630 bf = 0;
631 fsum = 0;
632 list = block_list;
633 block_list = NULL;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000634 free_list = NULL;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000635 while (list != NULL) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000636 bc++;
637 frem = 0;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000638 for (i = 0, p = &list->objects[0];
639 i < N_FLOATOBJECTS;
640 i++, p++) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000641 if (PyFloat_Check(p) && p->ob_refcnt != 0)
642 frem++;
643 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000644 next = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000645 if (frem) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000646 list->next = block_list;
647 block_list = list;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000648 for (i = 0, p = &list->objects[0];
649 i < N_FLOATOBJECTS;
650 i++, p++) {
651 if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
652 p->ob_type = (struct _typeobject *)
653 free_list;
654 free_list = p;
655 }
656 }
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000657 }
658 else {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000659 PyMem_FREE(list);
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000660 bf++;
661 }
662 fsum += frem;
Guido van Rossum3fce8831999-03-12 19:43:17 +0000663 list = next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000664 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000665 if (!Py_VerboseFlag)
666 return;
667 fprintf(stderr, "# cleanup floats");
668 if (!fsum) {
669 fprintf(stderr, "\n");
670 }
671 else {
672 fprintf(stderr,
673 ": %d unfreed float%s in %d out of %d block%s\n",
674 fsum, fsum == 1 ? "" : "s",
675 bc - bf, bc, bc == 1 ? "" : "s");
676 }
677 if (Py_VerboseFlag > 1) {
678 list = block_list;
679 while (list != NULL) {
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000680 for (i = 0, p = &list->objects[0];
681 i < N_FLOATOBJECTS;
682 i++, p++) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000683 if (PyFloat_Check(p) && p->ob_refcnt != 0) {
684 char buf[100];
685 PyFloat_AsString(buf, p);
686 fprintf(stderr,
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000687 "# <float at %lx, refcnt=%d, val=%s>\n",
Guido van Rossum3fce8831999-03-12 19:43:17 +0000688 p, p->ob_refcnt, buf);
689 }
690 }
691 list = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000692 }
693 }
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000694}