New \grammartoken markup, similar to \token but allowed everywhere.
[python/dscho.git] / Objects / floatobject.c
blob044d1d3af8c2a126ee90d4366e42fe52cd8b26e9
2 /* Float object implementation */
4 /* XXX There should be overflow checks here, but it's hard to check
5 for any kind of float exception without losing portability. */
7 #include "Python.h"
9 #include <ctype.h>
11 #ifdef i860
12 /* Cray APP has bogus definition of HUGE_VAL in <math.h> */
13 #undef HUGE_VAL
14 #endif
16 #if defined(HUGE_VAL) && !defined(CHECK)
17 #define CHECK(x) if (errno != 0) ; \
18 else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
19 else errno = ERANGE
20 #endif
22 #ifndef CHECK
23 #define CHECK(x) /* Don't know how to check */
24 #endif
26 #if !defined(__STDC__) && !defined(macintosh)
27 extern double fmod(double, double);
28 extern double pow(double, double);
29 #endif
31 #if defined(sun) && !defined(__SVR4)
32 /* On SunOS4.1 only libm.a exists. Make sure that references to all
33 needed math functions exist in the executable, so that dynamic
34 loading of mathmodule does not fail. */
35 double (*_Py_math_funcs_hack[])() = {
36 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor,
37 fmod, log, log10, pow, sin, sinh, sqrt, tan, tanh
39 #endif
41 /* Special free list -- see comments for same code in intobject.c. */
42 #define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
43 #define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
44 #define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
46 struct _floatblock {
47 struct _floatblock *next;
48 PyFloatObject objects[N_FLOATOBJECTS];
51 typedef struct _floatblock PyFloatBlock;
53 static PyFloatBlock *block_list = NULL;
54 static PyFloatObject *free_list = NULL;
56 static PyFloatObject *
57 fill_free_list(void)
59 PyFloatObject *p, *q;
60 /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
61 p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
62 if (p == NULL)
63 return (PyFloatObject *) PyErr_NoMemory();
64 ((PyFloatBlock *)p)->next = block_list;
65 block_list = (PyFloatBlock *)p;
66 p = &((PyFloatBlock *)p)->objects[0];
67 q = p + N_FLOATOBJECTS;
68 while (--q > p)
69 q->ob_type = (struct _typeobject *)(q-1);
70 q->ob_type = NULL;
71 return p + N_FLOATOBJECTS - 1;
74 PyObject *
75 PyFloat_FromDouble(double fval)
77 register PyFloatObject *op;
78 if (free_list == NULL) {
79 if ((free_list = fill_free_list()) == NULL)
80 return NULL;
82 /* PyObject_New is inlined */
83 op = free_list;
84 free_list = (PyFloatObject *)op->ob_type;
85 PyObject_INIT(op, &PyFloat_Type);
86 op->ob_fval = fval;
87 return (PyObject *) op;
90 /**************************************************************************
91 RED_FLAG 22-Sep-2000 tim
92 PyFloat_FromString's pend argument is braindead. Prior to this RED_FLAG,
94 1. If v was a regular string, *pend was set to point to its terminating
95 null byte. That's useless (the caller can find that without any
96 help from this function!).
98 2. If v was a Unicode string, or an object convertible to a character
99 buffer, *pend was set to point into stack trash (the auto temp
100 vector holding the character buffer). That was downright dangerous.
102 Since we can't change the interface of a public API function, pend is
103 still supported but now *officially* useless: if pend is not NULL,
104 *pend is set to NULL.
105 **************************************************************************/
106 PyObject *
107 PyFloat_FromString(PyObject *v, char **pend)
109 const char *s, *last, *end;
110 double x;
111 char buffer[256]; /* for errors */
112 #ifdef Py_USING_UNICODE
113 char s_buffer[256]; /* for objects convertible to a char buffer */
114 #endif
115 int len;
117 if (pend)
118 *pend = NULL;
119 if (PyString_Check(v)) {
120 s = PyString_AS_STRING(v);
121 len = PyString_GET_SIZE(v);
123 #ifdef Py_USING_UNICODE
124 else if (PyUnicode_Check(v)) {
125 if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
126 PyErr_SetString(PyExc_ValueError,
127 "Unicode float() literal too long to convert");
128 return NULL;
130 if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
131 PyUnicode_GET_SIZE(v),
132 s_buffer,
133 NULL))
134 return NULL;
135 s = s_buffer;
136 len = (int)strlen(s);
138 #endif
139 else if (PyObject_AsCharBuffer(v, &s, &len)) {
140 PyErr_SetString(PyExc_TypeError,
141 "float() needs a string argument");
142 return NULL;
145 last = s + len;
146 while (*s && isspace(Py_CHARMASK(*s)))
147 s++;
148 if (*s == '\0') {
149 PyErr_SetString(PyExc_ValueError, "empty string for float()");
150 return NULL;
152 /* We don't care about overflow or underflow. If the platform supports
153 * them, infinities and signed zeroes (on underflow) are fine.
154 * However, strtod can return 0 for denormalized numbers, where atof
155 * does not. So (alas!) we special-case a zero result. Note that
156 * whether strtod sets errno on underflow is not defined, so we can't
157 * key off errno.
159 PyFPE_START_PROTECT("strtod", return NULL)
160 x = strtod(s, (char **)&end);
161 PyFPE_END_PROTECT(x)
162 errno = 0;
163 /* Believe it or not, Solaris 2.6 can move end *beyond* the null
164 byte at the end of the string, when the input is inf(inity). */
165 if (end > last)
166 end = last;
167 if (end == s) {
168 sprintf(buffer, "invalid literal for float(): %.200s", s);
169 PyErr_SetString(PyExc_ValueError, buffer);
170 return NULL;
172 /* Since end != s, the platform made *some* kind of sense out
173 of the input. Trust it. */
174 while (*end && isspace(Py_CHARMASK(*end)))
175 end++;
176 if (*end != '\0') {
177 sprintf(buffer, "invalid literal for float(): %.200s", s);
178 PyErr_SetString(PyExc_ValueError, buffer);
179 return NULL;
181 else if (end != last) {
182 PyErr_SetString(PyExc_ValueError,
183 "null byte in argument for float()");
184 return NULL;
186 if (x == 0.0) {
187 /* See above -- may have been strtod being anal
188 about denorms. */
189 PyFPE_START_PROTECT("atof", return NULL)
190 x = atof(s);
191 PyFPE_END_PROTECT(x)
192 errno = 0; /* whether atof ever set errno is undefined */
194 return PyFloat_FromDouble(x);
197 static void
198 float_dealloc(PyFloatObject *op)
200 op->ob_type = (struct _typeobject *)free_list;
201 free_list = op;
204 double
205 PyFloat_AsDouble(PyObject *op)
207 PyNumberMethods *nb;
208 PyFloatObject *fo;
209 double val;
211 if (op && PyFloat_Check(op))
212 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
214 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
215 nb->nb_float == NULL) {
216 PyErr_BadArgument();
217 return -1;
220 fo = (PyFloatObject*) (*nb->nb_float) (op);
221 if (fo == NULL)
222 return -1;
223 if (!PyFloat_Check(fo)) {
224 PyErr_SetString(PyExc_TypeError,
225 "nb_float should return float object");
226 return -1;
229 val = PyFloat_AS_DOUBLE(fo);
230 Py_DECREF(fo);
232 return val;
235 /* Methods */
237 void
238 PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
240 register char *cp;
241 /* Subroutine for float_repr and float_print.
242 We want float numbers to be recognizable as such,
243 i.e., they should contain a decimal point or an exponent.
244 However, %g may print the number as an integer;
245 in such cases, we append ".0" to the string. */
246 sprintf(buf, "%.*g", precision, v->ob_fval);
247 cp = buf;
248 if (*cp == '-')
249 cp++;
250 for (; *cp != '\0'; cp++) {
251 /* Any non-digit means it's not an integer;
252 this takes care of NAN and INF as well. */
253 if (!isdigit(Py_CHARMASK(*cp)))
254 break;
256 if (*cp == '\0') {
257 *cp++ = '.';
258 *cp++ = '0';
259 *cp++ = '\0';
263 /* Macro and helper that convert PyObject obj to a C double and store
264 the value in dbl; this replaces the functionality of the coercion
265 slot function */
267 #define CONVERT_TO_DOUBLE(obj, dbl) \
268 if (PyFloat_Check(obj)) \
269 dbl = PyFloat_AS_DOUBLE(obj); \
270 else if (convert_to_double(&(obj), &(dbl)) < 0) \
271 return obj;
273 static int
274 convert_to_double(PyObject **v,
275 double *dbl)
277 register PyObject *obj = *v;
279 if (PyInt_Check(obj)) {
280 *dbl = (double)PyInt_AS_LONG(obj);
282 else if (PyLong_Check(obj)) {
283 PyFPE_START_PROTECT("convert_to_double", {*v=NULL;return -1;})
284 *dbl = PyLong_AsDouble(obj);
285 PyFPE_END_PROTECT(*dbl)
287 else {
288 Py_INCREF(Py_NotImplemented);
289 *v = Py_NotImplemented;
290 return -1;
292 return 0;
295 /* Precisions used by repr() and str(), respectively.
297 The repr() precision (17 significant decimal digits) is the minimal number
298 that is guaranteed to have enough precision so that if the number is read
299 back in the exact same binary value is recreated. This is true for IEEE
300 floating point by design, and also happens to work for all other modern
301 hardware.
303 The str() precision is chosen so that in most cases, the rounding noise
304 created by various operations is suppressed, while giving plenty of
305 precision for practical use.
309 #define PREC_REPR 17
310 #define PREC_STR 12
312 void
313 PyFloat_AsString(char *buf, PyFloatObject *v)
315 PyFloat_AsStringEx(buf, v, PREC_STR);
318 void
319 PyFloat_AsReprString(char *buf, PyFloatObject *v)
321 PyFloat_AsStringEx(buf, v, PREC_REPR);
324 /* ARGSUSED */
325 static int
326 float_print(PyFloatObject *v, FILE *fp, int flags)
328 char buf[100];
329 PyFloat_AsStringEx(buf, v, flags&Py_PRINT_RAW ? PREC_STR : PREC_REPR);
330 fputs(buf, fp);
331 return 0;
334 static PyObject *
335 float_repr(PyFloatObject *v)
337 char buf[100];
338 PyFloat_AsStringEx(buf, v, PREC_REPR);
339 return PyString_FromString(buf);
342 static PyObject *
343 float_str(PyFloatObject *v)
345 char buf[100];
346 PyFloat_AsStringEx(buf, v, PREC_STR);
347 return PyString_FromString(buf);
350 static int
351 float_compare(PyFloatObject *v, PyFloatObject *w)
353 double i = v->ob_fval;
354 double j = w->ob_fval;
355 return (i < j) ? -1 : (i > j) ? 1 : 0;
358 static long
359 float_hash(PyFloatObject *v)
361 return _Py_HashDouble(v->ob_fval);
364 static PyObject *
365 float_add(PyObject *v, PyObject *w)
367 double a,b;
368 CONVERT_TO_DOUBLE(v, a);
369 CONVERT_TO_DOUBLE(w, b);
370 PyFPE_START_PROTECT("add", return 0)
371 a = a + b;
372 PyFPE_END_PROTECT(a)
373 return PyFloat_FromDouble(a);
376 static PyObject *
377 float_sub(PyObject *v, PyObject *w)
379 double a,b;
380 CONVERT_TO_DOUBLE(v, a);
381 CONVERT_TO_DOUBLE(w, b);
382 PyFPE_START_PROTECT("subtract", return 0)
383 a = a - b;
384 PyFPE_END_PROTECT(a)
385 return PyFloat_FromDouble(a);
388 static PyObject *
389 float_mul(PyObject *v, PyObject *w)
391 double a,b;
392 CONVERT_TO_DOUBLE(v, a);
393 CONVERT_TO_DOUBLE(w, b);
394 PyFPE_START_PROTECT("multiply", return 0)
395 a = a * b;
396 PyFPE_END_PROTECT(a)
397 return PyFloat_FromDouble(a);
400 static PyObject *
401 float_div(PyObject *v, PyObject *w)
403 double a,b;
404 CONVERT_TO_DOUBLE(v, a);
405 CONVERT_TO_DOUBLE(w, b);
406 if (b == 0.0) {
407 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
408 return NULL;
410 PyFPE_START_PROTECT("divide", return 0)
411 a = a / b;
412 PyFPE_END_PROTECT(a)
413 return PyFloat_FromDouble(a);
416 static PyObject *
417 float_rem(PyObject *v, PyObject *w)
419 double vx, wx;
420 double mod;
421 CONVERT_TO_DOUBLE(v, vx);
422 CONVERT_TO_DOUBLE(w, wx);
423 if (wx == 0.0) {
424 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
425 return NULL;
427 PyFPE_START_PROTECT("modulo", return 0)
428 mod = fmod(vx, wx);
429 /* note: checking mod*wx < 0 is incorrect -- underflows to
430 0 if wx < sqrt(smallest nonzero double) */
431 if (mod && ((wx < 0) != (mod < 0))) {
432 mod += wx;
434 PyFPE_END_PROTECT(mod)
435 return PyFloat_FromDouble(mod);
438 static PyObject *
439 float_divmod(PyObject *v, PyObject *w)
441 double vx, wx;
442 double div, mod, floordiv;
443 CONVERT_TO_DOUBLE(v, vx);
444 CONVERT_TO_DOUBLE(w, wx);
445 if (wx == 0.0) {
446 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
447 return NULL;
449 PyFPE_START_PROTECT("divmod", return 0)
450 mod = fmod(vx, wx);
451 /* fmod is typically exact, so vx-mod is *mathematically* an
452 exact multiple of wx. But this is fp arithmetic, and fp
453 vx - mod is an approximation; the result is that div may
454 not be an exact integral value after the division, although
455 it will always be very close to one.
457 div = (vx - mod) / wx;
458 /* note: checking mod*wx < 0 is incorrect -- underflows to
459 0 if wx < sqrt(smallest nonzero double) */
460 if (mod && ((wx < 0) != (mod < 0))) {
461 mod += wx;
462 div -= 1.0;
464 /* snap quotient to nearest integral value */
465 floordiv = floor(div);
466 if (div - floordiv > 0.5)
467 floordiv += 1.0;
468 PyFPE_END_PROTECT(div)
469 return Py_BuildValue("(dd)", floordiv, mod);
472 static double powu(double x, long n)
474 double r = 1.;
475 double p = x;
476 long mask = 1;
477 while (mask > 0 && n >= mask) {
478 if (n & mask)
479 r *= p;
480 mask <<= 1;
481 p *= p;
483 return r;
486 static PyObject *
487 float_pow(PyObject *v, PyObject *w, PyObject *z)
489 double iv, iw, ix;
490 long intw;
491 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
492 * The z parameter is really only going to be useful for integers and
493 * long integers. Maybe something clever with logarithms could be done.
494 * [AMK]
496 CONVERT_TO_DOUBLE(v, iv);
497 CONVERT_TO_DOUBLE(w, iw);
498 intw = (long)iw;
500 /* Sort out special cases here instead of relying on pow() */
501 if (iw == 0) { /* x**0 is 1, even 0**0 */
502 PyFPE_START_PROTECT("pow", return NULL)
503 if ((PyObject *)z != Py_None) {
504 double iz;
505 CONVERT_TO_DOUBLE(z, iz);
506 ix=fmod(1.0, iz);
507 if (ix!=0 && iz<0) ix+=iz;
509 else
510 ix = 1.0;
511 PyFPE_END_PROTECT(ix)
512 return PyFloat_FromDouble(ix);
514 if (iv == 0.0) {
515 if (iw < 0.0) {
516 PyErr_SetString(PyExc_ZeroDivisionError,
517 "0.0 cannot be raised to a negative power");
518 return NULL;
520 return PyFloat_FromDouble(0.0);
523 if (iw == intw && intw > LONG_MIN) {
524 /* ruled out LONG_MIN because -LONG_MIN isn't representable */
525 errno = 0;
526 PyFPE_START_PROTECT("pow", return NULL)
527 if (intw > 0)
528 ix = powu(iv, intw);
529 else
530 ix = 1./powu(iv, -intw);
531 PyFPE_END_PROTECT(ix)
533 else {
534 /* Sort out special cases here instead of relying on pow() */
535 if (iv < 0.0) {
536 PyErr_SetString(PyExc_ValueError,
537 "negative number cannot be raised to a fractional power");
538 return NULL;
540 errno = 0;
541 PyFPE_START_PROTECT("pow", return NULL)
542 ix = pow(iv, iw);
543 PyFPE_END_PROTECT(ix)
545 CHECK(ix);
546 if (errno != 0) {
547 /* XXX could it be another type of error? */
548 PyErr_SetFromErrno(PyExc_OverflowError);
549 return NULL;
551 if ((PyObject *)z != Py_None) {
552 double iz;
553 CONVERT_TO_DOUBLE(z, iz);
554 PyFPE_START_PROTECT("pow", return 0)
555 ix=fmod(ix, iz); /* XXX To Be Rewritten */
556 if (ix!=0 && ((iv<0 && iz>0) || (iv>0 && iz<0) )) {
557 ix+=iz;
559 PyFPE_END_PROTECT(ix)
561 return PyFloat_FromDouble(ix);
564 static PyObject *
565 float_int_div(PyObject *v, PyObject *w)
567 PyObject *t, *r;
569 t = float_divmod(v, w);
570 if (t != NULL) {
571 r = PyTuple_GET_ITEM(t, 0);
572 Py_INCREF(r);
573 Py_DECREF(t);
574 return r;
576 return NULL;
579 static PyObject *
580 float_neg(PyFloatObject *v)
582 return PyFloat_FromDouble(-v->ob_fval);
585 static PyObject *
586 float_pos(PyFloatObject *v)
588 Py_INCREF(v);
589 return (PyObject *)v;
592 static PyObject *
593 float_abs(PyFloatObject *v)
595 if (v->ob_fval < 0)
596 return float_neg(v);
597 else
598 return float_pos(v);
601 static int
602 float_nonzero(PyFloatObject *v)
604 return v->ob_fval != 0.0;
607 static int
608 float_coerce(PyObject **pv, PyObject **pw)
610 if (PyInt_Check(*pw)) {
611 long x = PyInt_AsLong(*pw);
612 *pw = PyFloat_FromDouble((double)x);
613 Py_INCREF(*pv);
614 return 0;
616 else if (PyLong_Check(*pw)) {
617 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
618 Py_INCREF(*pv);
619 return 0;
621 return 1; /* Can't do it */
624 static PyObject *
625 float_int(PyObject *v)
627 double x = PyFloat_AsDouble(v);
628 double wholepart; /* integral portion of x, rounded toward 0 */
629 long aslong; /* (long)wholepart */
631 (void)modf(x, &wholepart);
632 /* doubles may have more bits than longs, or vice versa; and casting
633 to long may yield gibberish in either case. What really matters
634 is whether converting back to double again reproduces what we
635 started with. */
636 aslong = (long)wholepart;
637 if ((double)aslong == wholepart)
638 return PyInt_FromLong(aslong);
639 PyErr_SetString(PyExc_OverflowError, "float too large to convert");
640 return NULL;
643 static PyObject *
644 float_long(PyObject *v)
646 double x = PyFloat_AsDouble(v);
647 return PyLong_FromDouble(x);
650 static PyObject *
651 float_float(PyObject *v)
653 Py_INCREF(v);
654 return v;
658 static PyObject *
659 float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
661 PyObject *x = Py_False; /* Integer zero */
662 static char *kwlist[] = {"x", 0};
664 assert(type == &PyFloat_Type);
665 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
666 return NULL;
667 if (PyString_Check(x))
668 return PyFloat_FromString(x, NULL);
669 return PyNumber_Float(x);
672 static char float_doc[] =
673 "float(x) -> floating point number\n\
675 Convert a string or number to a floating point number, if possible.";
678 static PyNumberMethods float_as_number = {
679 (binaryfunc)float_add, /*nb_add*/
680 (binaryfunc)float_sub, /*nb_subtract*/
681 (binaryfunc)float_mul, /*nb_multiply*/
682 (binaryfunc)float_div, /*nb_divide*/
683 (binaryfunc)float_rem, /*nb_remainder*/
684 (binaryfunc)float_divmod, /*nb_divmod*/
685 (ternaryfunc)float_pow, /*nb_power*/
686 (unaryfunc)float_neg, /*nb_negative*/
687 (unaryfunc)float_pos, /*nb_positive*/
688 (unaryfunc)float_abs, /*nb_absolute*/
689 (inquiry)float_nonzero, /*nb_nonzero*/
690 0, /*nb_invert*/
691 0, /*nb_lshift*/
692 0, /*nb_rshift*/
693 0, /*nb_and*/
694 0, /*nb_xor*/
695 0, /*nb_or*/
696 (coercion)float_coerce, /*nb_coerce*/
697 (unaryfunc)float_int, /*nb_int*/
698 (unaryfunc)float_long, /*nb_long*/
699 (unaryfunc)float_float, /*nb_float*/
700 0, /* nb_oct */
701 0, /* nb_hex */
702 0, /* nb_inplace_add */
703 0, /* nb_inplace_subtract */
704 0, /* nb_inplace_multiply */
705 0, /* nb_inplace_divide */
706 0, /* nb_inplace_remainder */
707 0, /* nb_inplace_power */
708 0, /* nb_inplace_lshift */
709 0, /* nb_inplace_rshift */
710 0, /* nb_inplace_and */
711 0, /* nb_inplace_xor */
712 0, /* nb_inplace_or */
713 float_int_div, /* nb_floor_divide */
714 float_div, /* nb_true_divide */
715 0, /* nb_inplace_floor_divide */
716 0, /* nb_inplace_true_divide */
719 PyTypeObject PyFloat_Type = {
720 PyObject_HEAD_INIT(&PyType_Type)
722 "float",
723 sizeof(PyFloatObject),
725 (destructor)float_dealloc, /* tp_dealloc */
726 (printfunc)float_print, /* tp_print */
727 0, /* tp_getattr */
728 0, /* tp_setattr */
729 (cmpfunc)float_compare, /* tp_compare */
730 (reprfunc)float_repr, /* tp_repr */
731 &float_as_number, /* tp_as_number */
732 0, /* tp_as_sequence */
733 0, /* tp_as_mapping */
734 (hashfunc)float_hash, /* tp_hash */
735 0, /* tp_call */
736 (reprfunc)float_str, /* tp_str */
737 PyObject_GenericGetAttr, /* tp_getattro */
738 0, /* tp_setattro */
739 0, /* tp_as_buffer */
740 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
741 float_doc, /* tp_doc */
742 0, /* tp_traverse */
743 0, /* tp_clear */
744 0, /* tp_richcompare */
745 0, /* tp_weaklistoffset */
746 0, /* tp_iter */
747 0, /* tp_iternext */
748 0, /* tp_methods */
749 0, /* tp_members */
750 0, /* tp_getset */
751 0, /* tp_base */
752 0, /* tp_dict */
753 0, /* tp_descr_get */
754 0, /* tp_descr_set */
755 0, /* tp_dictoffset */
756 0, /* tp_init */
757 0, /* tp_alloc */
758 float_new, /* tp_new */
761 void
762 PyFloat_Fini(void)
764 PyFloatObject *p;
765 PyFloatBlock *list, *next;
766 int i;
767 int bc, bf; /* block count, number of freed blocks */
768 int frem, fsum; /* remaining unfreed floats per block, total */
770 bc = 0;
771 bf = 0;
772 fsum = 0;
773 list = block_list;
774 block_list = NULL;
775 free_list = NULL;
776 while (list != NULL) {
777 bc++;
778 frem = 0;
779 for (i = 0, p = &list->objects[0];
780 i < N_FLOATOBJECTS;
781 i++, p++) {
782 if (PyFloat_Check(p) && p->ob_refcnt != 0)
783 frem++;
785 next = list->next;
786 if (frem) {
787 list->next = block_list;
788 block_list = list;
789 for (i = 0, p = &list->objects[0];
790 i < N_FLOATOBJECTS;
791 i++, p++) {
792 if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
793 p->ob_type = (struct _typeobject *)
794 free_list;
795 free_list = p;
799 else {
800 PyMem_FREE(list); /* XXX PyObject_FREE ??? */
801 bf++;
803 fsum += frem;
804 list = next;
806 if (!Py_VerboseFlag)
807 return;
808 fprintf(stderr, "# cleanup floats");
809 if (!fsum) {
810 fprintf(stderr, "\n");
812 else {
813 fprintf(stderr,
814 ": %d unfreed float%s in %d out of %d block%s\n",
815 fsum, fsum == 1 ? "" : "s",
816 bc - bf, bc, bc == 1 ? "" : "s");
818 if (Py_VerboseFlag > 1) {
819 list = block_list;
820 while (list != NULL) {
821 for (i = 0, p = &list->objects[0];
822 i < N_FLOATOBJECTS;
823 i++, p++) {
824 if (PyFloat_Check(p) && p->ob_refcnt != 0) {
825 char buf[100];
826 PyFloat_AsString(buf, p);
827 fprintf(stderr,
828 "# <float at %p, refcnt=%d, val=%s>\n",
829 p, p->ob_refcnt, buf);
832 list = list->next;