blob: 7a444ad50980a97860a703eda64f5d36e0d6a7fd [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* Float object implementation */
12
Guido van Rossum2a9096b1990-10-21 22:15:08 +000013/* XXX There should be overflow checks here, but it's hard to check
14 for any kind of float exception without losing portability. */
15
Guido van Rossumc0b618a1997-05-02 03:12:38 +000016#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000017
Guido van Rossum3f5da241990-12-20 15:06:42 +000018#include <ctype.h>
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000019#include "mymath.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000020
Guido van Rossum9575a441993-04-07 14:06:14 +000021#ifdef i860
22/* Cray APP has bogus definition of HUGE_VAL in <math.h> */
23#undef HUGE_VAL
24#endif
25
Guido van Rossum9d81b551996-06-26 18:27:19 +000026#if defined(HUGE_VAL) && !defined(CHECK)
Guido van Rossum7fa52f81991-12-16 15:43:14 +000027#define CHECK(x) if (errno != 0) ; \
28 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
29 else errno = ERANGE
Guido van Rossum9d81b551996-06-26 18:27:19 +000030#endif
31
32#ifndef CHECK
Guido van Rossum7fa52f81991-12-16 15:43:14 +000033#define CHECK(x) /* Don't know how to check */
34#endif
35
Guido van Rossum03093a21994-09-28 15:51:32 +000036#ifdef HAVE_LIMITS_H
37#include <limits.h>
38#endif
39
40#ifndef LONG_MAX
Fred Drake13634cf2000-06-29 19:17:04 +000041#if SIZEOF_LONG == 4
Guido van Rossum03093a21994-09-28 15:51:32 +000042#define LONG_MAX 0X7FFFFFFFL
Fred Drake13634cf2000-06-29 19:17:04 +000043#elif SIZEOF_LONG == 8
44#define LONG_MAX 0X7FFFFFFFFFFFFFFFL
45#else
46#error "could not set LONG_MAX"
47#endif
Guido van Rossum03093a21994-09-28 15:51:32 +000048#endif
49
50#ifndef LONG_MIN
51#define LONG_MIN (-LONG_MAX-1)
52#endif
53
Guido van Rossum67ca7011995-02-13 16:38:41 +000054#ifdef __NeXT__
55#ifdef __sparc__
56/*
57 * This works around a bug in the NS/Sparc 3.3 pre-release
58 * limits.h header file.
59 * 10-Feb-1995 bwarsaw@cnri.reston.va.us
60 */
61#undef LONG_MIN
62#define LONG_MIN (-LONG_MAX-1)
63#endif
64#endif
65
Guido van Rossum07e3a7e1995-02-27 10:13:37 +000066#if !defined(__STDC__) && !defined(macintosh)
Tim Petersdbd9ba62000-07-09 03:09:57 +000067extern double fmod(double, double);
68extern double pow(double, double);
Guido van Rossum6923e131990-11-02 17:50:43 +000069#endif
70
Guido van Rossum3c03fa81997-10-31 17:00:30 +000071#ifdef sun
72/* On SunOS4.1 only libm.a exists. Make sure that references to all
73 needed math functions exist in the executable, so that dynamic
74 loading of mathmodule does not fail. */
75double (*_Py_math_funcs_hack[])() = {
76 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor,
77 fmod, log, log10, pow, sin, sinh, sqrt, tan, tanh
78};
79#endif
80
Guido van Rossum93ad0df1997-05-13 21:00:42 +000081/* Special free list -- see comments for same code in intobject.c. */
Guido van Rossum93ad0df1997-05-13 21:00:42 +000082#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
Guido van Rossum3fce8831999-03-12 19:43:17 +000083#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
Guido van Rossumf61bbc81999-03-12 00:12:21 +000084#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
Guido van Rossum3fce8831999-03-12 19:43:17 +000085
Guido van Rossum3fce8831999-03-12 19:43:17 +000086struct _floatblock {
87 struct _floatblock *next;
88 PyFloatObject objects[N_FLOATOBJECTS];
89};
90
91typedef struct _floatblock PyFloatBlock;
92
93static PyFloatBlock *block_list = NULL;
94static PyFloatObject *free_list = NULL;
95
Guido van Rossum93ad0df1997-05-13 21:00:42 +000096static PyFloatObject *
Fred Drakefd99de62000-07-09 05:02:18 +000097fill_free_list(void)
Guido van Rossum93ad0df1997-05-13 21:00:42 +000098{
99 PyFloatObject *p, *q;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000100 /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
101 p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000102 if (p == NULL)
Guido van Rossumb18618d2000-05-03 23:44:39 +0000103 return (PyFloatObject *) PyErr_NoMemory();
Guido van Rossum3fce8831999-03-12 19:43:17 +0000104 ((PyFloatBlock *)p)->next = block_list;
105 block_list = (PyFloatBlock *)p;
106 p = &((PyFloatBlock *)p)->objects[0];
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000107 q = p + N_FLOATOBJECTS;
108 while (--q > p)
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000109 q->ob_type = (struct _typeobject *)(q-1);
110 q->ob_type = NULL;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000111 return p + N_FLOATOBJECTS - 1;
112}
113
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000114PyObject *
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000115PyFloat_FromDouble(double fval)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116{
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000117 register PyFloatObject *op;
118 if (free_list == NULL) {
119 if ((free_list = fill_free_list()) == NULL)
120 return NULL;
121 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000122 /* PyObject_New is inlined */
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000123 op = free_list;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000124 free_list = (PyFloatObject *)op->ob_type;
Guido van Rossumb18618d2000-05-03 23:44:39 +0000125 PyObject_INIT(op, &PyFloat_Type);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000126 op->ob_fval = fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000127 return (PyObject *) op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000128}
129
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000130PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000131PyFloat_FromString(PyObject *v, char **pend)
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000132{
Tim Petersdbd9ba62000-07-09 03:09:57 +0000133 extern double strtod(const char *, char **);
Guido van Rossum4c08d552000-03-10 22:55:18 +0000134 const char *s, *last, *end;
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000135 double x;
136 char buffer[256]; /* For errors */
Guido van Rossum4c08d552000-03-10 22:55:18 +0000137 int len;
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000138
Guido van Rossum4c08d552000-03-10 22:55:18 +0000139 if (PyString_Check(v)) {
140 s = PyString_AS_STRING(v);
141 len = PyString_GET_SIZE(v);
142 }
Guido van Rossum9e896b32000-04-05 20:11:21 +0000143 else if (PyUnicode_Check(v)) {
144 char s_buffer[256];
145
146 if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
147 PyErr_SetString(PyExc_ValueError,
148 "float() literal too large to convert");
149 return NULL;
150 }
151 if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
152 PyUnicode_GET_SIZE(v),
153 s_buffer,
154 NULL))
155 return NULL;
156 s = s_buffer;
157 len = strlen(s);
158 }
Guido van Rossum4c08d552000-03-10 22:55:18 +0000159 else if (PyObject_AsCharBuffer(v, &s, &len)) {
160 PyErr_SetString(PyExc_TypeError,
161 "float() needs a string argument");
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000162 return NULL;
Guido van Rossum4c08d552000-03-10 22:55:18 +0000163 }
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000164
Guido van Rossum4c08d552000-03-10 22:55:18 +0000165 last = s + len;
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000166 while (*s && isspace(Py_CHARMASK(*s)))
167 s++;
168 if (s[0] == '\0') {
169 PyErr_SetString(PyExc_ValueError, "empty string for float()");
170 return NULL;
171 }
172 errno = 0;
173 PyFPE_START_PROTECT("PyFloat_FromString", return 0)
Guido van Rossum4c08d552000-03-10 22:55:18 +0000174 x = strtod((char *)s, (char **)&end);
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000175 PyFPE_END_PROTECT(x)
176 /* Believe it or not, Solaris 2.6 can move end *beyond* the null
177 byte at the end of the string, when the input is inf(inity) */
178 if (end > last)
179 end = last;
180 while (*end && isspace(Py_CHARMASK(*end)))
181 end++;
182 if (*end != '\0') {
183 sprintf(buffer, "invalid literal for float(): %.200s", s);
184 PyErr_SetString(PyExc_ValueError, buffer);
185 return NULL;
186 }
Guido van Rossum4c08d552000-03-10 22:55:18 +0000187 else if (end != last) {
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000188 PyErr_SetString(PyExc_ValueError,
189 "null byte in argument for float()");
190 return NULL;
191 }
192 else if (errno != 0) {
193 sprintf(buffer, "float() literal too large: %.200s", s);
194 PyErr_SetString(PyExc_ValueError, buffer);
195 return NULL;
196 }
197 if (pend)
Guido van Rossum4c08d552000-03-10 22:55:18 +0000198 *pend = (char *)end;
Barry Warsaw226ae6c1999-10-12 19:54:53 +0000199 return PyFloat_FromDouble(x);
200}
201
Guido van Rossum234f9421993-06-17 12:35:49 +0000202static void
Fred Drakefd99de62000-07-09 05:02:18 +0000203float_dealloc(PyFloatObject *op)
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000204{
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000205 op->ob_type = (struct _typeobject *)free_list;
Guido van Rossum93ad0df1997-05-13 21:00:42 +0000206 free_list = op;
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000207}
208
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209double
Fred Drakefd99de62000-07-09 05:02:18 +0000210PyFloat_AsDouble(PyObject *op)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000212 PyNumberMethods *nb;
213 PyFloatObject *fo;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214 double val;
215
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000216 if (op && PyFloat_Check(op))
217 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
220 nb->nb_float == NULL) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000221 PyErr_BadArgument();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 return -1;
223 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000225 fo = (PyFloatObject*) (*nb->nb_float) (op);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226 if (fo == NULL)
227 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000228 if (!PyFloat_Check(fo)) {
229 PyErr_SetString(PyExc_TypeError,
230 "nb_float should return float object");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231 return -1;
232 }
233
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000234 val = PyFloat_AS_DOUBLE(fo);
235 Py_DECREF(fo);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236
237 return val;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238}
239
240/* Methods */
241
Guido van Rossum27dec7e1991-06-04 19:42:53 +0000242void
Fred Drakefd99de62000-07-09 05:02:18 +0000243PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000244{
245 register char *cp;
246 /* Subroutine for float_repr and float_print.
247 We want float numbers to be recognizable as such,
248 i.e., they should contain a decimal point or an exponent.
249 However, %g may print the number as an integer;
250 in such cases, we append ".0" to the string. */
Guido van Rossum57072eb1999-12-23 19:00:28 +0000251 sprintf(buf, "%.*g", precision, v->ob_fval);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252 cp = buf;
253 if (*cp == '-')
254 cp++;
255 for (; *cp != '\0'; cp++) {
256 /* Any non-digit means it's not an integer;
257 this takes care of NAN and INF as well. */
Guido van Rossum9fa2c111995-02-10 17:00:37 +0000258 if (!isdigit(Py_CHARMASK(*cp)))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000259 break;
260 }
261 if (*cp == '\0') {
262 *cp++ = '.';
263 *cp++ = '0';
264 *cp++ = '\0';
265 }
266}
267
Guido van Rossum57072eb1999-12-23 19:00:28 +0000268/* Precisions used by repr() and str(), respectively.
269
270 The repr() precision (17 significant decimal digits) is the minimal number
271 that is guaranteed to have enough precision so that if the number is read
272 back in the exact same binary value is recreated. This is true for IEEE
273 floating point by design, and also happens to work for all other modern
274 hardware.
275
276 The str() precision is chosen so that in most cases, the rounding noise
277 created by various operations is suppressed, while giving plenty of
278 precision for practical use.
279
280*/
281
282#define PREC_REPR 17
283#define PREC_STR 12
284
285void
Fred Drakefd99de62000-07-09 05:02:18 +0000286PyFloat_AsString(char *buf, PyFloatObject *v)
Guido van Rossum57072eb1999-12-23 19:00:28 +0000287{
288 PyFloat_AsStringEx(buf, v, PREC_STR);
289}
290
Guido van Rossum3132a5a1992-03-27 17:28:44 +0000291/* ARGSUSED */
Guido van Rossum90933611991-06-07 16:10:43 +0000292static int
Fred Drakefd99de62000-07-09 05:02:18 +0000293float_print(PyFloatObject *v, FILE *fp, int flags)
294 /* flags -- not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295{
296 char buf[100];
Guido van Rossum57072eb1999-12-23 19:00:28 +0000297 PyFloat_AsStringEx(buf, v, flags&Py_PRINT_RAW ? PREC_STR : PREC_REPR);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 fputs(buf, fp);
Guido van Rossum90933611991-06-07 16:10:43 +0000299 return 0;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300}
301
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000302static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000303float_repr(PyFloatObject *v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304{
305 char buf[100];
Guido van Rossum57072eb1999-12-23 19:00:28 +0000306 PyFloat_AsStringEx(buf, v, PREC_REPR);
307 return PyString_FromString(buf);
308}
309
310static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000311float_str(PyFloatObject *v)
Guido van Rossum57072eb1999-12-23 19:00:28 +0000312{
313 char buf[100];
314 PyFloat_AsStringEx(buf, v, PREC_STR);
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000315 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316}
317
318static int
Fred Drakefd99de62000-07-09 05:02:18 +0000319float_compare(PyFloatObject *v, PyFloatObject *w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320{
321 double i = v->ob_fval;
322 double j = w->ob_fval;
323 return (i < j) ? -1 : (i > j) ? 1 : 0;
324}
325
Fred Drake13634cf2000-06-29 19:17:04 +0000326
Guido van Rossum9bfef441993-03-29 10:43:31 +0000327static long
Fred Drakefd99de62000-07-09 05:02:18 +0000328float_hash(PyFloatObject *v)
Guido van Rossum9bfef441993-03-29 10:43:31 +0000329{
330 double intpart, fractpart;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000331 long x;
332 /* This is designed so that Python numbers with the same
333 value hash to the same value, otherwise comparisons
334 of mapping keys will turn out weird */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000335
336#ifdef MPW /* MPW C modf expects pointer to extended as second argument */
337{
338 extended e;
339 fractpart = modf(v->ob_fval, &e);
340 intpart = e;
341}
342#else
Guido van Rossum9bfef441993-03-29 10:43:31 +0000343 fractpart = modf(v->ob_fval, &intpart);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000344#endif
345
Guido van Rossum9bfef441993-03-29 10:43:31 +0000346 if (fractpart == 0.0) {
Fred Drake13634cf2000-06-29 19:17:04 +0000347 if (intpart > LONG_MAX || -intpart > LONG_MAX) {
Guido van Rossum9bfef441993-03-29 10:43:31 +0000348 /* Convert to long int and use its hash... */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000349 PyObject *w = PyLong_FromDouble(v->ob_fval);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000350 if (w == NULL)
351 return -1;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000352 x = PyObject_Hash(w);
353 Py_DECREF(w);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000354 return x;
355 }
356 x = (long)intpart;
357 }
358 else {
Guido van Rossum919cf1a1997-01-11 19:26:21 +0000359 /* Note -- if you change this code, also change the copy
360 in complexobject.c */
Fred Drake13634cf2000-06-29 19:17:04 +0000361 x = _Py_HashDouble(v->ob_fval);
362 if (x == -1)
363 return -1;
Guido van Rossum9bfef441993-03-29 10:43:31 +0000364 }
365 if (x == -1)
366 x = -2;
367 return x;
368}
369
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000370static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000371float_add(PyFloatObject *v, PyFloatObject *w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000372{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000373 double result;
374 PyFPE_START_PROTECT("add", return 0)
375 result = v->ob_fval + w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000376 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000377 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000378}
379
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000380static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000381float_sub(PyFloatObject *v, PyFloatObject *w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000382{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000383 double result;
384 PyFPE_START_PROTECT("subtract", return 0)
385 result = v->ob_fval - w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000386 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000387 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388}
389
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000390static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000391float_mul(PyFloatObject *v, PyFloatObject *w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000393 double result;
394
395 PyFPE_START_PROTECT("multiply", return 0)
396 result = v->ob_fval * w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000397 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000398 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000399}
400
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000401static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000402float_div(PyFloatObject *v, PyFloatObject *w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000403{
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000404 double result;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000405 if (w->ob_fval == 0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000406 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 return NULL;
408 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000409 PyFPE_START_PROTECT("divide", return 0)
410 result = v->ob_fval / w->ob_fval;
Guido van Rossum45b83911997-03-14 04:32:50 +0000411 PyFPE_END_PROTECT(result)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000412 return PyFloat_FromDouble(result);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000413}
414
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000415static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000416float_rem(PyFloatObject *v, PyFloatObject *w)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417{
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000418 double vx, wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000419 double mod;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000420 wx = w->ob_fval;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000422 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000423 return NULL;
424 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000425 PyFPE_START_PROTECT("modulo", return 0)
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000426 vx = v->ob_fval;
427 mod = fmod(vx, wx);
Guido van Rossum9263e781999-05-06 14:26:34 +0000428 /* note: checking mod*wx < 0 is incorrect -- underflows to
429 0 if wx < sqrt(smallest nonzero double) */
430 if (mod && ((wx < 0) != (mod < 0))) {
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000431 mod += wx;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000432 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000433 PyFPE_END_PROTECT(mod)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000434 return PyFloat_FromDouble(mod);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000435}
436
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000437static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000438float_divmod(PyFloatObject *v, PyFloatObject *w)
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000439{
Guido van Rossum15ecff41991-10-20 20:16:45 +0000440 double vx, wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000441 double div, mod, floordiv;
Guido van Rossum56cd67a1992-01-26 18:16:35 +0000442 wx = w->ob_fval;
Guido van Rossum15ecff41991-10-20 20:16:45 +0000443 if (wx == 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000444 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
Guido van Rossum15ecff41991-10-20 20:16:45 +0000445 return NULL;
446 }
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000447 PyFPE_START_PROTECT("divmod", return 0)
Guido van Rossum15ecff41991-10-20 20:16:45 +0000448 vx = v->ob_fval;
449 mod = fmod(vx, wx);
Guido van Rossum9263e781999-05-06 14:26:34 +0000450 /* fmod is typically exact, so vx-mod is *mathemtically* an
451 exact multiple of wx. But this is fp arithmetic, and fp
452 vx - mod is an approximation; the result is that div may
453 not be an exact integral value after the division, although
454 it will always be very close to one.
455 */
Guido van Rossum15ecff41991-10-20 20:16:45 +0000456 div = (vx - mod) / wx;
Guido van Rossum9263e781999-05-06 14:26:34 +0000457 /* note: checking mod*wx < 0 is incorrect -- underflows to
458 0 if wx < sqrt(smallest nonzero double) */
459 if (mod && ((wx < 0) != (mod < 0))) {
Guido van Rossum15ecff41991-10-20 20:16:45 +0000460 mod += wx;
461 div -= 1.0;
462 }
Guido van Rossum9263e781999-05-06 14:26:34 +0000463 /* snap quotient to nearest integral value */
464 floordiv = floor(div);
465 if (div - floordiv > 0.5)
466 floordiv += 1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000467 PyFPE_END_PROTECT(div)
Guido van Rossum9263e781999-05-06 14:26:34 +0000468 return Py_BuildValue("(dd)", floordiv, mod);
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000469}
470
Fred Drakefd99de62000-07-09 05:02:18 +0000471static double powu(double x, long n)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000472{
473 double r = 1.;
474 double p = x;
475 long mask = 1;
476 while (mask > 0 && n >= mask) {
477 if (n & mask)
478 r *= p;
479 mask <<= 1;
480 p *= p;
481 }
482 return r;
483}
484
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000485static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000486float_pow(PyFloatObject *v, PyObject *w, PyFloatObject *z)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487{
488 double iv, iw, ix;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000489 long intw;
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000490 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
491 * The z parameter is really only going to be useful for integers and
492 * long integers. Maybe something clever with logarithms could be done.
493 * [AMK]
494 */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000495 iv = v->ob_fval;
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000496 iw = ((PyFloatObject *)w)->ob_fval;
Guido van Rossum39739ea1996-01-12 01:22:56 +0000497 intw = (long)iw;
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000498 if (iw == intw && -10000 < intw && intw < 10000) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000499 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum86c04c21996-08-09 20:50:14 +0000500 if (intw == 0) { /* x**0 is 1, even 0**0 */
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000501 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000502 if ((PyObject *)z!=Py_None) {
Guido van Rossum39739ea1996-01-12 01:22:56 +0000503 ix=fmod(1.0, z->ob_fval);
504 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
505 }
506 else ix=1.0;
Guido van Rossum45b83911997-03-14 04:32:50 +0000507 PyFPE_END_PROTECT(ix)
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000508 return PyFloat_FromDouble(ix);
Guido van Rossum70d93461991-05-28 21:57:39 +0000509 }
Guido van Rossum86c04c21996-08-09 20:50:14 +0000510 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000511 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000512 if (intw > 0)
513 ix = powu(iv, intw);
514 else
515 ix = 1./powu(iv, -intw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000516 PyFPE_END_PROTECT(ix)
Guido van Rossum86c04c21996-08-09 20:50:14 +0000517 }
518 else {
519 /* Sort out special cases here instead of relying on pow() */
Guido van Rossum39739ea1996-01-12 01:22:56 +0000520 if (iv == 0.0) {
521 if (iw < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000522 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000523 "0.0 to a negative power");
Guido van Rossum39739ea1996-01-12 01:22:56 +0000524 return NULL;
525 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000526 return PyFloat_FromDouble(0.0);
Guido van Rossum39739ea1996-01-12 01:22:56 +0000527 }
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000528 if (iv < 0.0) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000529 PyErr_SetString(PyExc_ValueError,
Guido van Rossumc13bcca1996-08-16 20:42:57 +0000530 "negative number to a float power");
531 return NULL;
532 }
Guido van Rossum39739ea1996-01-12 01:22:56 +0000533 errno = 0;
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000534 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum39739ea1996-01-12 01:22:56 +0000535 ix = pow(iv, iw);
Guido van Rossum45b83911997-03-14 04:32:50 +0000536 PyFPE_END_PROTECT(ix)
Guido van Rossum70d93461991-05-28 21:57:39 +0000537 }
Guido van Rossum7fa52f81991-12-16 15:43:14 +0000538 CHECK(ix);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000539 if (errno != 0) {
540 /* XXX could it be another type of error? */
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000541 PyErr_SetFromErrno(PyExc_OverflowError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000542 return NULL;
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000543 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000544 if ((PyObject *)z!=Py_None) {
Guido van Rossum09e6ad01997-02-14 22:54:21 +0000545 PyFPE_START_PROTECT("pow", return 0)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000546 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
547 if ( ix!=0 &&
548 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
549 ix+=z->ob_fval;
550 }
Guido van Rossum45b83911997-03-14 04:32:50 +0000551 PyFPE_END_PROTECT(ix)
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000552 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000553 return PyFloat_FromDouble(ix);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000554}
555
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000556static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000557float_neg(PyFloatObject *v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000558{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000559 return PyFloat_FromDouble(-v->ob_fval);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000560}
561
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000562static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000563float_pos(PyFloatObject *v)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000565 Py_INCREF(v);
566 return (PyObject *)v;
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000567}
568
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000569static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000570float_abs(PyFloatObject *v)
Guido van Rossumeba1b5e1991-05-05 20:07:00 +0000571{
572 if (v->ob_fval < 0)
573 return float_neg(v);
574 else
575 return float_pos(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576}
577
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000578static int
Fred Drakefd99de62000-07-09 05:02:18 +0000579float_nonzero(PyFloatObject *v)
Guido van Rossum50b4ef61991-05-14 11:57:01 +0000580{
581 return v->ob_fval != 0.0;
582}
583
Guido van Rossum234f9421993-06-17 12:35:49 +0000584static int
Fred Drakefd99de62000-07-09 05:02:18 +0000585float_coerce(PyObject **pv, PyObject **pw)
Guido van Rossume6eefc21992-08-14 12:06:52 +0000586{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000587 if (PyInt_Check(*pw)) {
588 long x = PyInt_AsLong(*pw);
589 *pw = PyFloat_FromDouble((double)x);
590 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000591 return 0;
592 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000593 else if (PyLong_Check(*pw)) {
594 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
595 Py_INCREF(*pv);
Guido van Rossume6eefc21992-08-14 12:06:52 +0000596 return 0;
597 }
598 return 1; /* Can't do it */
599}
600
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000601static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000602float_int(PyObject *v)
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000603{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000604 double x = PyFloat_AsDouble(v);
Guido van Rossum03093a21994-09-28 15:51:32 +0000605 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
606 : (x = floor(x)) > (double)LONG_MAX) {
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000607 PyErr_SetString(PyExc_OverflowError,
608 "float too large to convert");
Guido van Rossum03093a21994-09-28 15:51:32 +0000609 return NULL;
610 }
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000611 return PyInt_FromLong((long)x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000612}
613
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000614static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000615float_long(PyObject *v)
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000616{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000617 double x = PyFloat_AsDouble(v);
618 return PyLong_FromDouble(x);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000619}
620
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000621static PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +0000622float_float(PyObject *v)
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000623{
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000624 Py_INCREF(v);
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000625 return v;
626}
627
628
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000629static PyNumberMethods float_as_number = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000630 (binaryfunc)float_add, /*nb_add*/
631 (binaryfunc)float_sub, /*nb_subtract*/
632 (binaryfunc)float_mul, /*nb_multiply*/
633 (binaryfunc)float_div, /*nb_divide*/
634 (binaryfunc)float_rem, /*nb_remainder*/
635 (binaryfunc)float_divmod, /*nb_divmod*/
Guido van Rossum0b7d02a1994-08-12 12:52:35 +0000636 (ternaryfunc)float_pow, /*nb_power*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000637 (unaryfunc)float_neg, /*nb_negative*/
638 (unaryfunc)float_pos, /*nb_positive*/
639 (unaryfunc)float_abs, /*nb_absolute*/
640 (inquiry)float_nonzero, /*nb_nonzero*/
Guido van Rossum27acb331991-10-24 14:55:28 +0000641 0, /*nb_invert*/
642 0, /*nb_lshift*/
643 0, /*nb_rshift*/
644 0, /*nb_and*/
645 0, /*nb_xor*/
646 0, /*nb_or*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000647 (coercion)float_coerce, /*nb_coerce*/
648 (unaryfunc)float_int, /*nb_int*/
649 (unaryfunc)float_long, /*nb_long*/
650 (unaryfunc)float_float, /*nb_float*/
Guido van Rossum1899c2e1992-09-12 11:09:23 +0000651 0, /*nb_oct*/
652 0, /*nb_hex*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000653};
654
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000655PyTypeObject PyFloat_Type = {
656 PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000657 0,
658 "float",
Guido van Rossumc0b618a1997-05-02 03:12:38 +0000659 sizeof(PyFloatObject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660 0,
Guido van Rossumb6775db1994-08-01 11:34:53 +0000661 (destructor)float_dealloc, /*tp_dealloc*/
662 (printfunc)float_print, /*tp_print*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000663 0, /*tp_getattr*/
664 0, /*tp_setattr*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000665 (cmpfunc)float_compare, /*tp_compare*/
Guido van Rossum57072eb1999-12-23 19:00:28 +0000666 (reprfunc)float_repr, /*tp_repr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667 &float_as_number, /*tp_as_number*/
668 0, /*tp_as_sequence*/
669 0, /*tp_as_mapping*/
Guido van Rossum57072eb1999-12-23 19:00:28 +0000670 (hashfunc)float_hash, /*tp_hash*/
671 0, /*tp_call*/
672 (reprfunc)float_str, /*tp_str*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000673};
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000674
675void
Fred Drakefd99de62000-07-09 05:02:18 +0000676PyFloat_Fini(void)
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000677{
Guido van Rossum3fce8831999-03-12 19:43:17 +0000678 PyFloatObject *p;
679 PyFloatBlock *list, *next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000680 int i;
681 int bc, bf; /* block count, number of freed blocks */
682 int frem, fsum; /* remaining unfreed floats per block, total */
683
684 bc = 0;
685 bf = 0;
686 fsum = 0;
687 list = block_list;
688 block_list = NULL;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000689 free_list = NULL;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000690 while (list != NULL) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000691 bc++;
692 frem = 0;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000693 for (i = 0, p = &list->objects[0];
694 i < N_FLOATOBJECTS;
695 i++, p++) {
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000696 if (PyFloat_Check(p) && p->ob_refcnt != 0)
697 frem++;
698 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000699 next = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000700 if (frem) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000701 list->next = block_list;
702 block_list = list;
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000703 for (i = 0, p = &list->objects[0];
704 i < N_FLOATOBJECTS;
705 i++, p++) {
706 if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
707 p->ob_type = (struct _typeobject *)
708 free_list;
709 free_list = p;
710 }
711 }
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000712 }
713 else {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000714 PyMem_FREE(list); /* XXX PyObject_FREE ??? */
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000715 bf++;
716 }
717 fsum += frem;
Guido van Rossum3fce8831999-03-12 19:43:17 +0000718 list = next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000719 }
Guido van Rossum3fce8831999-03-12 19:43:17 +0000720 if (!Py_VerboseFlag)
721 return;
722 fprintf(stderr, "# cleanup floats");
723 if (!fsum) {
724 fprintf(stderr, "\n");
725 }
726 else {
727 fprintf(stderr,
728 ": %d unfreed float%s in %d out of %d block%s\n",
729 fsum, fsum == 1 ? "" : "s",
730 bc - bf, bc, bc == 1 ? "" : "s");
731 }
732 if (Py_VerboseFlag > 1) {
733 list = block_list;
734 while (list != NULL) {
Guido van Rossumd7b5fb81999-03-19 20:59:40 +0000735 for (i = 0, p = &list->objects[0];
736 i < N_FLOATOBJECTS;
737 i++, p++) {
Guido van Rossum3fce8831999-03-12 19:43:17 +0000738 if (PyFloat_Check(p) && p->ob_refcnt != 0) {
739 char buf[100];
740 PyFloat_AsString(buf, p);
741 fprintf(stderr,
Fred Drakea44d3532000-06-30 15:01:00 +0000742 "# <float at %p, refcnt=%d, val=%s>\n",
743 p, p->ob_refcnt, buf);
Guido van Rossum3fce8831999-03-12 19:43:17 +0000744 }
745 }
746 list = list->next;
Guido van Rossumf61bbc81999-03-12 00:12:21 +0000747 }
748 }
Guido van Rossumfbbd57e1997-08-05 02:16:08 +0000749}