Improved some error messages for command line processing.
[python/dscho.git] / Objects / floatobject.c
blob070e83def9af0ccf7fb14a0ce034763c54f80bca
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Float object implementation */
34 /* XXX There should be overflow checks here, but it's hard to check
35 for any kind of float exception without losing portability. */
37 #include "Python.h"
39 #include <ctype.h>
40 #include "mymath.h"
42 #ifdef i860
43 /* Cray APP has bogus definition of HUGE_VAL in <math.h> */
44 #undef HUGE_VAL
45 #endif
47 #if defined(HUGE_VAL) && !defined(CHECK)
48 #define CHECK(x) if (errno != 0) ; \
49 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
50 else errno = ERANGE
51 #endif
53 #ifndef CHECK
54 #define CHECK(x) /* Don't know how to check */
55 #endif
57 #ifdef HAVE_LIMITS_H
58 #include <limits.h>
59 #endif
61 #ifndef LONG_MAX
62 #define LONG_MAX 0X7FFFFFFFL
63 #endif
65 #ifndef LONG_MIN
66 #define LONG_MIN (-LONG_MAX-1)
67 #endif
69 #ifdef __NeXT__
70 #ifdef __sparc__
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
76 #undef LONG_MIN
77 #define LONG_MIN (-LONG_MAX-1)
78 #endif
79 #endif
81 #if !defined(__STDC__) && !defined(macintosh)
82 extern double fmod Py_PROTO((double, double));
83 extern double pow Py_PROTO((double, double));
84 #endif
86 #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. */
90 double (*_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
94 #endif
96 /* Special free list -- see comments for same code in intobject.c. */
97 static PyFloatObject *free_list = NULL;
98 #define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
99 #define N_FLOATOBJECTS (BLOCK_SIZE / sizeof(PyFloatObject))
101 static PyFloatObject *
102 fill_free_list()
104 PyFloatObject *p, *q;
105 p = PyMem_NEW(PyFloatObject, N_FLOATOBJECTS);
106 if (p == NULL)
107 return (PyFloatObject *)PyErr_NoMemory();
108 q = p + N_FLOATOBJECTS;
109 while (--q > p)
110 *(PyFloatObject **)q = q-1;
111 *(PyFloatObject **)q = NULL;
112 return p + N_FLOATOBJECTS - 1;
115 PyObject *
116 #ifdef __SC__
117 PyFloat_FromDouble(double fval)
118 #else
119 PyFloat_FromDouble(fval)
120 double fval;
121 #endif
123 register PyFloatObject *op;
124 if (free_list == NULL) {
125 if ((free_list = fill_free_list()) == NULL)
126 return NULL;
128 op = free_list;
129 free_list = *(PyFloatObject **)free_list;
130 op->ob_type = &PyFloat_Type;
131 op->ob_fval = fval;
132 _Py_NewReference(op);
133 return (PyObject *) op;
136 static void
137 float_dealloc(op)
138 PyFloatObject *op;
140 *(PyFloatObject **)op = free_list;
141 free_list = op;
144 double
145 PyFloat_AsDouble(op)
146 PyObject *op;
148 PyNumberMethods *nb;
149 PyFloatObject *fo;
150 double val;
152 if (op && PyFloat_Check(op))
153 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
155 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
156 nb->nb_float == NULL) {
157 PyErr_BadArgument();
158 return -1;
161 fo = (PyFloatObject*) (*nb->nb_float) (op);
162 if (fo == NULL)
163 return -1;
164 if (!PyFloat_Check(fo)) {
165 PyErr_SetString(PyExc_TypeError,
166 "nb_float should return float object");
167 return -1;
170 val = PyFloat_AS_DOUBLE(fo);
171 Py_DECREF(fo);
173 return val;
176 /* Methods */
178 void
179 PyFloat_AsString(buf, v)
180 char *buf;
181 PyFloatObject *v;
183 register char *cp;
184 /* Subroutine for float_repr and float_print.
185 We want float numbers to be recognizable as such,
186 i.e., they should contain a decimal point or an exponent.
187 However, %g may print the number as an integer;
188 in such cases, we append ".0" to the string. */
189 sprintf(buf, "%.12g", v->ob_fval);
190 cp = buf;
191 if (*cp == '-')
192 cp++;
193 for (; *cp != '\0'; cp++) {
194 /* Any non-digit means it's not an integer;
195 this takes care of NAN and INF as well. */
196 if (!isdigit(Py_CHARMASK(*cp)))
197 break;
199 if (*cp == '\0') {
200 *cp++ = '.';
201 *cp++ = '0';
202 *cp++ = '\0';
206 /* ARGSUSED */
207 static int
208 float_print(v, fp, flags)
209 PyFloatObject *v;
210 FILE *fp;
211 int flags; /* Not used but required by interface */
213 char buf[100];
214 PyFloat_AsString(buf, v);
215 fputs(buf, fp);
216 return 0;
219 static PyObject *
220 float_repr(v)
221 PyFloatObject *v;
223 char buf[100];
224 PyFloat_AsString(buf, v);
225 return PyString_FromString(buf);
228 static int
229 float_compare(v, w)
230 PyFloatObject *v, *w;
232 double i = v->ob_fval;
233 double j = w->ob_fval;
234 return (i < j) ? -1 : (i > j) ? 1 : 0;
237 static long
238 float_hash(v)
239 PyFloatObject *v;
241 double intpart, fractpart;
242 int expo;
243 long x;
244 /* This is designed so that Python numbers with the same
245 value hash to the same value, otherwise comparisons
246 of mapping keys will turn out weird */
248 #ifdef MPW /* MPW C modf expects pointer to extended as second argument */
250 extended e;
251 fractpart = modf(v->ob_fval, &e);
252 intpart = e;
254 #else
255 fractpart = modf(v->ob_fval, &intpart);
256 #endif
258 if (fractpart == 0.0) {
259 if (intpart > 0x7fffffffL || -intpart > 0x7fffffffL) {
260 /* Convert to long int and use its hash... */
261 PyObject *w = PyLong_FromDouble(v->ob_fval);
262 if (w == NULL)
263 return -1;
264 x = PyObject_Hash(w);
265 Py_DECREF(w);
266 return x;
268 x = (long)intpart;
270 else {
271 /* Note -- if you change this code, also change the copy
272 in complexobject.c */
273 long hipart;
274 fractpart = frexp(fractpart, &expo);
275 fractpart = fractpart * 2147483648.0; /* 2**31 */
276 hipart = (long)fractpart; /* Take the top 32 bits */
277 fractpart = (fractpart - (double)hipart) * 2147483648.0;
278 /* Get the next 32 bits */
279 x = hipart + (long)fractpart + (long)intpart + (expo << 15);
280 /* Combine everything */
282 if (x == -1)
283 x = -2;
284 return x;
287 static PyObject *
288 float_add(v, w)
289 PyFloatObject *v;
290 PyFloatObject *w;
292 double result;
293 PyFPE_START_PROTECT("add", return 0)
294 result = v->ob_fval + w->ob_fval;
295 PyFPE_END_PROTECT(result)
296 return PyFloat_FromDouble(result);
299 static PyObject *
300 float_sub(v, w)
301 PyFloatObject *v;
302 PyFloatObject *w;
304 double result;
305 PyFPE_START_PROTECT("subtract", return 0)
306 result = v->ob_fval - w->ob_fval;
307 PyFPE_END_PROTECT(result)
308 return PyFloat_FromDouble(result);
311 static PyObject *
312 float_mul(v, w)
313 PyFloatObject *v;
314 PyFloatObject *w;
316 double result;
318 PyFPE_START_PROTECT("multiply", return 0)
319 result = v->ob_fval * w->ob_fval;
320 PyFPE_END_PROTECT(result)
321 return PyFloat_FromDouble(result);
324 static PyObject *
325 float_div(v, w)
326 PyFloatObject *v;
327 PyFloatObject *w;
329 double result;
330 if (w->ob_fval == 0) {
331 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
332 return NULL;
334 PyFPE_START_PROTECT("divide", return 0)
335 result = v->ob_fval / w->ob_fval;
336 PyFPE_END_PROTECT(result)
337 return PyFloat_FromDouble(result);
340 static PyObject *
341 float_rem(v, w)
342 PyFloatObject *v;
343 PyFloatObject *w;
345 double vx, wx;
346 double /* div, */ mod;
347 wx = w->ob_fval;
348 if (wx == 0.0) {
349 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
350 return NULL;
352 PyFPE_START_PROTECT("modulo", return 0)
353 vx = v->ob_fval;
354 mod = fmod(vx, wx);
355 /* div = (vx - mod) / wx; */
356 if (wx*mod < 0) {
357 mod += wx;
358 /* div -= 1.0; */
360 PyFPE_END_PROTECT(mod)
361 return PyFloat_FromDouble(mod);
364 static PyObject *
365 float_divmod(v, w)
366 PyFloatObject *v;
367 PyFloatObject *w;
369 double vx, wx;
370 double div, mod;
371 wx = w->ob_fval;
372 if (wx == 0.0) {
373 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
374 return NULL;
376 PyFPE_START_PROTECT("divmod", return 0)
377 vx = v->ob_fval;
378 mod = fmod(vx, wx);
379 div = (vx - mod) / wx;
380 if (wx*mod < 0) {
381 mod += wx;
382 div -= 1.0;
384 PyFPE_END_PROTECT(div)
385 return Py_BuildValue("(dd)", div, mod);
388 static double powu(x, n)
389 double x;
390 long n;
392 double r = 1.;
393 double p = x;
394 long mask = 1;
395 while (mask > 0 && n >= mask) {
396 if (n & mask)
397 r *= p;
398 mask <<= 1;
399 p *= p;
401 return r;
404 static PyObject *
405 float_pow(v, w, z)
406 PyFloatObject *v;
407 PyObject *w;
408 PyFloatObject *z;
410 double iv, iw, ix;
411 long intw;
412 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
413 * The z parameter is really only going to be useful for integers and
414 * long integers. Maybe something clever with logarithms could be done.
415 * [AMK]
417 iv = v->ob_fval;
418 iw = ((PyFloatObject *)w)->ob_fval;
419 intw = (long)iw;
420 if (iw == intw && -10000 < intw && intw < 10000) {
421 /* Sort out special cases here instead of relying on pow() */
422 if (intw == 0) { /* x**0 is 1, even 0**0 */
423 PyFPE_START_PROTECT("pow", return 0)
424 if ((PyObject *)z!=Py_None) {
425 ix=fmod(1.0, z->ob_fval);
426 if (ix!=0 && z->ob_fval<0) ix+=z->ob_fval;
428 else ix=1.0;
429 PyFPE_END_PROTECT(ix)
430 return PyFloat_FromDouble(ix);
432 errno = 0;
433 PyFPE_START_PROTECT("pow", return 0)
434 if (intw > 0)
435 ix = powu(iv, intw);
436 else
437 ix = 1./powu(iv, -intw);
438 PyFPE_END_PROTECT(ix)
440 else {
441 /* Sort out special cases here instead of relying on pow() */
442 if (iv == 0.0) {
443 if (iw < 0.0) {
444 PyErr_SetString(PyExc_ValueError,
445 "0.0 to a negative power");
446 return NULL;
448 return PyFloat_FromDouble(0.0);
450 if (iv < 0.0) {
451 PyErr_SetString(PyExc_ValueError,
452 "negative number to a float power");
453 return NULL;
455 errno = 0;
456 PyFPE_START_PROTECT("pow", return 0)
457 ix = pow(iv, iw);
458 PyFPE_END_PROTECT(ix)
460 CHECK(ix);
461 if (errno != 0) {
462 /* XXX could it be another type of error? */
463 PyErr_SetFromErrno(PyExc_OverflowError);
464 return NULL;
466 if ((PyObject *)z!=Py_None) {
467 PyFPE_START_PROTECT("pow", return 0)
468 ix=fmod(ix, z->ob_fval); /* XXX To Be Rewritten */
469 if ( ix!=0 &&
470 ((iv<0 && z->ob_fval>0) || (iv>0 && z->ob_fval<0) )) {
471 ix+=z->ob_fval;
473 PyFPE_END_PROTECT(ix)
475 return PyFloat_FromDouble(ix);
478 static PyObject *
479 float_neg(v)
480 PyFloatObject *v;
482 return PyFloat_FromDouble(-v->ob_fval);
485 static PyObject *
486 float_pos(v)
487 PyFloatObject *v;
489 Py_INCREF(v);
490 return (PyObject *)v;
493 static PyObject *
494 float_abs(v)
495 PyFloatObject *v;
497 if (v->ob_fval < 0)
498 return float_neg(v);
499 else
500 return float_pos(v);
503 static int
504 float_nonzero(v)
505 PyFloatObject *v;
507 return v->ob_fval != 0.0;
510 static int
511 float_coerce(pv, pw)
512 PyObject **pv;
513 PyObject **pw;
515 if (PyInt_Check(*pw)) {
516 long x = PyInt_AsLong(*pw);
517 *pw = PyFloat_FromDouble((double)x);
518 Py_INCREF(*pv);
519 return 0;
521 else if (PyLong_Check(*pw)) {
522 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
523 Py_INCREF(*pv);
524 return 0;
526 return 1; /* Can't do it */
529 static PyObject *
530 float_int(v)
531 PyObject *v;
533 double x = PyFloat_AsDouble(v);
534 if (x < 0 ? (x = ceil(x)) < (double)LONG_MIN
535 : (x = floor(x)) > (double)LONG_MAX) {
536 PyErr_SetString(PyExc_OverflowError,
537 "float too large to convert");
538 return NULL;
540 return PyInt_FromLong((long)x);
543 static PyObject *
544 float_long(v)
545 PyObject *v;
547 double x = PyFloat_AsDouble(v);
548 return PyLong_FromDouble(x);
551 static PyObject *
552 float_float(v)
553 PyObject *v;
555 Py_INCREF(v);
556 return v;
560 static PyNumberMethods float_as_number = {
561 (binaryfunc)float_add, /*nb_add*/
562 (binaryfunc)float_sub, /*nb_subtract*/
563 (binaryfunc)float_mul, /*nb_multiply*/
564 (binaryfunc)float_div, /*nb_divide*/
565 (binaryfunc)float_rem, /*nb_remainder*/
566 (binaryfunc)float_divmod, /*nb_divmod*/
567 (ternaryfunc)float_pow, /*nb_power*/
568 (unaryfunc)float_neg, /*nb_negative*/
569 (unaryfunc)float_pos, /*nb_positive*/
570 (unaryfunc)float_abs, /*nb_absolute*/
571 (inquiry)float_nonzero, /*nb_nonzero*/
572 0, /*nb_invert*/
573 0, /*nb_lshift*/
574 0, /*nb_rshift*/
575 0, /*nb_and*/
576 0, /*nb_xor*/
577 0, /*nb_or*/
578 (coercion)float_coerce, /*nb_coerce*/
579 (unaryfunc)float_int, /*nb_int*/
580 (unaryfunc)float_long, /*nb_long*/
581 (unaryfunc)float_float, /*nb_float*/
582 0, /*nb_oct*/
583 0, /*nb_hex*/
586 PyTypeObject PyFloat_Type = {
587 PyObject_HEAD_INIT(&PyType_Type)
589 "float",
590 sizeof(PyFloatObject),
592 (destructor)float_dealloc, /*tp_dealloc*/
593 (printfunc)float_print, /*tp_print*/
594 0, /*tp_getattr*/
595 0, /*tp_setattr*/
596 (cmpfunc)float_compare, /*tp_compare*/
597 (reprfunc)float_repr, /*tp_repr*/
598 &float_as_number, /*tp_as_number*/
599 0, /*tp_as_sequence*/
600 0, /*tp_as_mapping*/
601 (hashfunc)float_hash, /*tp_hash*/
604 void
605 PyFloat_Fini()
607 /* XXX Alas, the free list is not easily and safely freeable */