Merged release21-maint changes.
[python/dscho.git] / Objects / floatobject.c
blob34b252bf722ce48527b51248b4c713ce8c453ea4
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 char s_buffer[256]; /* for objects convertible to a char buffer */
113 int len;
115 if (pend)
116 *pend = NULL;
117 if (PyString_Check(v)) {
118 s = PyString_AS_STRING(v);
119 len = PyString_GET_SIZE(v);
121 else if (PyUnicode_Check(v)) {
122 if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) {
123 PyErr_SetString(PyExc_ValueError,
124 "Unicode float() literal too long to convert");
125 return NULL;
127 if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
128 PyUnicode_GET_SIZE(v),
129 s_buffer,
130 NULL))
131 return NULL;
132 s = s_buffer;
133 len = (int)strlen(s);
135 else if (PyObject_AsCharBuffer(v, &s, &len)) {
136 PyErr_SetString(PyExc_TypeError,
137 "float() needs a string argument");
138 return NULL;
141 last = s + len;
142 while (*s && isspace(Py_CHARMASK(*s)))
143 s++;
144 if (*s == '\0') {
145 PyErr_SetString(PyExc_ValueError, "empty string for float()");
146 return NULL;
148 /* We don't care about overflow or underflow. If the platform supports
149 * them, infinities and signed zeroes (on underflow) are fine.
150 * However, strtod can return 0 for denormalized numbers, where atof
151 * does not. So (alas!) we special-case a zero result. Note that
152 * whether strtod sets errno on underflow is not defined, so we can't
153 * key off errno.
155 PyFPE_START_PROTECT("strtod", return NULL)
156 x = strtod(s, (char **)&end);
157 PyFPE_END_PROTECT(x)
158 errno = 0;
159 /* Believe it or not, Solaris 2.6 can move end *beyond* the null
160 byte at the end of the string, when the input is inf(inity). */
161 if (end > last)
162 end = last;
163 if (end == s) {
164 sprintf(buffer, "invalid literal for float(): %.200s", s);
165 PyErr_SetString(PyExc_ValueError, buffer);
166 return NULL;
168 /* Since end != s, the platform made *some* kind of sense out
169 of the input. Trust it. */
170 while (*end && isspace(Py_CHARMASK(*end)))
171 end++;
172 if (*end != '\0') {
173 sprintf(buffer, "invalid literal for float(): %.200s", s);
174 PyErr_SetString(PyExc_ValueError, buffer);
175 return NULL;
177 else if (end != last) {
178 PyErr_SetString(PyExc_ValueError,
179 "null byte in argument for float()");
180 return NULL;
182 if (x == 0.0) {
183 /* See above -- may have been strtod being anal
184 about denorms. */
185 PyFPE_START_PROTECT("atof", return NULL)
186 x = atof(s);
187 PyFPE_END_PROTECT(x)
188 errno = 0; /* whether atof ever set errno is undefined */
190 return PyFloat_FromDouble(x);
193 static void
194 float_dealloc(PyFloatObject *op)
196 op->ob_type = (struct _typeobject *)free_list;
197 free_list = op;
200 double
201 PyFloat_AsDouble(PyObject *op)
203 PyNumberMethods *nb;
204 PyFloatObject *fo;
205 double val;
207 if (op && PyFloat_Check(op))
208 return PyFloat_AS_DOUBLE((PyFloatObject*) op);
210 if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL ||
211 nb->nb_float == NULL) {
212 PyErr_BadArgument();
213 return -1;
216 fo = (PyFloatObject*) (*nb->nb_float) (op);
217 if (fo == NULL)
218 return -1;
219 if (!PyFloat_Check(fo)) {
220 PyErr_SetString(PyExc_TypeError,
221 "nb_float should return float object");
222 return -1;
225 val = PyFloat_AS_DOUBLE(fo);
226 Py_DECREF(fo);
228 return val;
231 /* Methods */
233 void
234 PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
236 register char *cp;
237 /* Subroutine for float_repr and float_print.
238 We want float numbers to be recognizable as such,
239 i.e., they should contain a decimal point or an exponent.
240 However, %g may print the number as an integer;
241 in such cases, we append ".0" to the string. */
242 sprintf(buf, "%.*g", precision, v->ob_fval);
243 cp = buf;
244 if (*cp == '-')
245 cp++;
246 for (; *cp != '\0'; cp++) {
247 /* Any non-digit means it's not an integer;
248 this takes care of NAN and INF as well. */
249 if (!isdigit(Py_CHARMASK(*cp)))
250 break;
252 if (*cp == '\0') {
253 *cp++ = '.';
254 *cp++ = '0';
255 *cp++ = '\0';
259 /* Macro and helper that convert PyObject obj to a C double and store
260 the value in dbl; this replaces the functionality of the coercion
261 slot function */
263 #define CONVERT_TO_DOUBLE(obj, dbl) \
264 if (PyFloat_Check(obj)) \
265 dbl = PyFloat_AS_DOUBLE(obj); \
266 else if (convert_to_double(&(obj), &(dbl)) < 0) \
267 return obj;
269 static int
270 convert_to_double(PyObject **v,
271 double *dbl)
273 register PyObject *obj = *v;
275 if (PyInt_Check(obj)) {
276 *dbl = (double)PyInt_AS_LONG(obj);
278 else if (PyLong_Check(obj)) {
279 PyFPE_START_PROTECT("convert_to_double", {*v=NULL;return -1;})
280 *dbl = PyLong_AsDouble(obj);
281 PyFPE_END_PROTECT(*dbl)
283 else {
284 Py_INCREF(Py_NotImplemented);
285 *v = Py_NotImplemented;
286 return -1;
288 return 0;
291 /* Precisions used by repr() and str(), respectively.
293 The repr() precision (17 significant decimal digits) is the minimal number
294 that is guaranteed to have enough precision so that if the number is read
295 back in the exact same binary value is recreated. This is true for IEEE
296 floating point by design, and also happens to work for all other modern
297 hardware.
299 The str() precision is chosen so that in most cases, the rounding noise
300 created by various operations is suppressed, while giving plenty of
301 precision for practical use.
305 #define PREC_REPR 17
306 #define PREC_STR 12
308 void
309 PyFloat_AsString(char *buf, PyFloatObject *v)
311 PyFloat_AsStringEx(buf, v, PREC_STR);
314 void
315 PyFloat_AsReprString(char *buf, PyFloatObject *v)
317 PyFloat_AsStringEx(buf, v, PREC_REPR);
320 /* ARGSUSED */
321 static int
322 float_print(PyFloatObject *v, FILE *fp, int flags)
324 char buf[100];
325 PyFloat_AsStringEx(buf, v, flags&Py_PRINT_RAW ? PREC_STR : PREC_REPR);
326 fputs(buf, fp);
327 return 0;
330 static PyObject *
331 float_repr(PyFloatObject *v)
333 char buf[100];
334 PyFloat_AsStringEx(buf, v, PREC_REPR);
335 return PyString_FromString(buf);
338 static PyObject *
339 float_str(PyFloatObject *v)
341 char buf[100];
342 PyFloat_AsStringEx(buf, v, PREC_STR);
343 return PyString_FromString(buf);
346 static int
347 float_compare(PyFloatObject *v, PyFloatObject *w)
349 double i = v->ob_fval;
350 double j = w->ob_fval;
351 return (i < j) ? -1 : (i > j) ? 1 : 0;
354 static long
355 float_hash(PyFloatObject *v)
357 return _Py_HashDouble(v->ob_fval);
360 static PyObject *
361 float_add(PyObject *v, PyObject *w)
363 double a,b;
364 CONVERT_TO_DOUBLE(v, a);
365 CONVERT_TO_DOUBLE(w, b);
366 PyFPE_START_PROTECT("add", return 0)
367 a = a + b;
368 PyFPE_END_PROTECT(a)
369 return PyFloat_FromDouble(a);
372 static PyObject *
373 float_sub(PyObject *v, PyObject *w)
375 double a,b;
376 CONVERT_TO_DOUBLE(v, a);
377 CONVERT_TO_DOUBLE(w, b);
378 PyFPE_START_PROTECT("subtract", return 0)
379 a = a - b;
380 PyFPE_END_PROTECT(a)
381 return PyFloat_FromDouble(a);
384 static PyObject *
385 float_mul(PyObject *v, PyObject *w)
387 double a,b;
388 CONVERT_TO_DOUBLE(v, a);
389 CONVERT_TO_DOUBLE(w, b);
390 PyFPE_START_PROTECT("multiply", return 0)
391 a = a * b;
392 PyFPE_END_PROTECT(a)
393 return PyFloat_FromDouble(a);
396 static PyObject *
397 float_div(PyObject *v, PyObject *w)
399 double a,b;
400 CONVERT_TO_DOUBLE(v, a);
401 CONVERT_TO_DOUBLE(w, b);
402 if (b == 0.0) {
403 PyErr_SetString(PyExc_ZeroDivisionError, "float division");
404 return NULL;
406 PyFPE_START_PROTECT("divide", return 0)
407 a = a / b;
408 PyFPE_END_PROTECT(a)
409 return PyFloat_FromDouble(a);
412 static PyObject *
413 float_rem(PyObject *v, PyObject *w)
415 double vx, wx;
416 double mod;
417 CONVERT_TO_DOUBLE(v, vx);
418 CONVERT_TO_DOUBLE(w, wx);
419 if (wx == 0.0) {
420 PyErr_SetString(PyExc_ZeroDivisionError, "float modulo");
421 return NULL;
423 PyFPE_START_PROTECT("modulo", return 0)
424 mod = fmod(vx, wx);
425 /* note: checking mod*wx < 0 is incorrect -- underflows to
426 0 if wx < sqrt(smallest nonzero double) */
427 if (mod && ((wx < 0) != (mod < 0))) {
428 mod += wx;
430 PyFPE_END_PROTECT(mod)
431 return PyFloat_FromDouble(mod);
434 static PyObject *
435 float_divmod(PyObject *v, PyObject *w)
437 double vx, wx;
438 double div, mod, floordiv;
439 CONVERT_TO_DOUBLE(v, vx);
440 CONVERT_TO_DOUBLE(w, wx);
441 if (wx == 0.0) {
442 PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
443 return NULL;
445 PyFPE_START_PROTECT("divmod", return 0)
446 mod = fmod(vx, wx);
447 /* fmod is typically exact, so vx-mod is *mathematically* an
448 exact multiple of wx. But this is fp arithmetic, and fp
449 vx - mod is an approximation; the result is that div may
450 not be an exact integral value after the division, although
451 it will always be very close to one.
453 div = (vx - mod) / wx;
454 /* note: checking mod*wx < 0 is incorrect -- underflows to
455 0 if wx < sqrt(smallest nonzero double) */
456 if (mod && ((wx < 0) != (mod < 0))) {
457 mod += wx;
458 div -= 1.0;
460 /* snap quotient to nearest integral value */
461 floordiv = floor(div);
462 if (div - floordiv > 0.5)
463 floordiv += 1.0;
464 PyFPE_END_PROTECT(div)
465 return Py_BuildValue("(dd)", floordiv, mod);
468 static double powu(double x, long n)
470 double r = 1.;
471 double p = x;
472 long mask = 1;
473 while (mask > 0 && n >= mask) {
474 if (n & mask)
475 r *= p;
476 mask <<= 1;
477 p *= p;
479 return r;
482 static PyObject *
483 float_pow(PyObject *v, PyObject *w, PyObject *z)
485 double iv, iw, ix;
486 long intw;
487 /* XXX Doesn't handle overflows if z!=None yet; it may never do so :(
488 * The z parameter is really only going to be useful for integers and
489 * long integers. Maybe something clever with logarithms could be done.
490 * [AMK]
492 CONVERT_TO_DOUBLE(v, iv);
493 CONVERT_TO_DOUBLE(w, iw);
494 intw = (long)iw;
496 /* Sort out special cases here instead of relying on pow() */
497 if (iw == 0) { /* x**0 is 1, even 0**0 */
498 PyFPE_START_PROTECT("pow", return NULL)
499 if ((PyObject *)z != Py_None) {
500 double iz;
501 CONVERT_TO_DOUBLE(z, iz);
502 ix=fmod(1.0, iz);
503 if (ix!=0 && iz<0) ix+=iz;
505 else
506 ix = 1.0;
507 PyFPE_END_PROTECT(ix)
508 return PyFloat_FromDouble(ix);
510 if (iv == 0.0) {
511 if (iw < 0.0) {
512 PyErr_SetString(PyExc_ZeroDivisionError,
513 "0.0 cannot be raised to a negative power");
514 return NULL;
516 return PyFloat_FromDouble(0.0);
519 if (iw == intw && intw > LONG_MIN) {
520 /* ruled out LONG_MIN because -LONG_MIN isn't representable */
521 errno = 0;
522 PyFPE_START_PROTECT("pow", return NULL)
523 if (intw > 0)
524 ix = powu(iv, intw);
525 else
526 ix = 1./powu(iv, -intw);
527 PyFPE_END_PROTECT(ix)
529 else {
530 /* Sort out special cases here instead of relying on pow() */
531 if (iv < 0.0) {
532 PyErr_SetString(PyExc_ValueError,
533 "negative number cannot be raised to a fractional power");
534 return NULL;
536 errno = 0;
537 PyFPE_START_PROTECT("pow", return NULL)
538 ix = pow(iv, iw);
539 PyFPE_END_PROTECT(ix)
541 CHECK(ix);
542 if (errno != 0) {
543 /* XXX could it be another type of error? */
544 PyErr_SetFromErrno(PyExc_OverflowError);
545 return NULL;
547 if ((PyObject *)z != Py_None) {
548 double iz;
549 CONVERT_TO_DOUBLE(z, iz);
550 PyFPE_START_PROTECT("pow", return 0)
551 ix=fmod(ix, iz); /* XXX To Be Rewritten */
552 if (ix!=0 && ((iv<0 && iz>0) || (iv>0 && iz<0) )) {
553 ix+=iz;
555 PyFPE_END_PROTECT(ix)
557 return PyFloat_FromDouble(ix);
560 static PyObject *
561 float_int_div(PyObject *v, PyObject *w)
563 PyObject *t, *r;
565 t = float_divmod(v, w);
566 if (t != NULL) {
567 r = PyTuple_GET_ITEM(t, 0);
568 Py_INCREF(r);
569 Py_DECREF(t);
570 return r;
572 return NULL;
575 static PyObject *
576 float_neg(PyFloatObject *v)
578 return PyFloat_FromDouble(-v->ob_fval);
581 static PyObject *
582 float_pos(PyFloatObject *v)
584 Py_INCREF(v);
585 return (PyObject *)v;
588 static PyObject *
589 float_abs(PyFloatObject *v)
591 if (v->ob_fval < 0)
592 return float_neg(v);
593 else
594 return float_pos(v);
597 static int
598 float_nonzero(PyFloatObject *v)
600 return v->ob_fval != 0.0;
603 static int
604 float_coerce(PyObject **pv, PyObject **pw)
606 if (PyInt_Check(*pw)) {
607 long x = PyInt_AsLong(*pw);
608 *pw = PyFloat_FromDouble((double)x);
609 Py_INCREF(*pv);
610 return 0;
612 else if (PyLong_Check(*pw)) {
613 *pw = PyFloat_FromDouble(PyLong_AsDouble(*pw));
614 Py_INCREF(*pv);
615 return 0;
617 return 1; /* Can't do it */
620 static PyObject *
621 float_int(PyObject *v)
623 double x = PyFloat_AsDouble(v);
624 double wholepart; /* integral portion of x, rounded toward 0 */
625 long aslong; /* (long)wholepart */
627 (void)modf(x, &wholepart);
628 /* doubles may have more bits than longs, or vice versa; and casting
629 to long may yield gibberish in either case. What really matters
630 is whether converting back to double again reproduces what we
631 started with. */
632 aslong = (long)wholepart;
633 if ((double)aslong == wholepart)
634 return PyInt_FromLong(aslong);
635 PyErr_SetString(PyExc_OverflowError, "float too large to convert");
636 return NULL;
639 static PyObject *
640 float_long(PyObject *v)
642 double x = PyFloat_AsDouble(v);
643 return PyLong_FromDouble(x);
646 static PyObject *
647 float_float(PyObject *v)
649 Py_INCREF(v);
650 return v;
654 static PyObject *
655 float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
657 PyObject *x = Py_False; /* Integer zero */
658 static char *kwlist[] = {"x", 0};
660 assert(type == &PyFloat_Type);
661 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
662 return NULL;
663 if (PyString_Check(x))
664 return PyFloat_FromString(x, NULL);
665 return PyNumber_Float(x);
668 static char float_doc[] =
669 "float(x) -> floating point number\n\
671 Convert a string or number to a floating point number, if possible.";
674 static PyNumberMethods float_as_number = {
675 (binaryfunc)float_add, /*nb_add*/
676 (binaryfunc)float_sub, /*nb_subtract*/
677 (binaryfunc)float_mul, /*nb_multiply*/
678 (binaryfunc)float_div, /*nb_divide*/
679 (binaryfunc)float_rem, /*nb_remainder*/
680 (binaryfunc)float_divmod, /*nb_divmod*/
681 (ternaryfunc)float_pow, /*nb_power*/
682 (unaryfunc)float_neg, /*nb_negative*/
683 (unaryfunc)float_pos, /*nb_positive*/
684 (unaryfunc)float_abs, /*nb_absolute*/
685 (inquiry)float_nonzero, /*nb_nonzero*/
686 0, /*nb_invert*/
687 0, /*nb_lshift*/
688 0, /*nb_rshift*/
689 0, /*nb_and*/
690 0, /*nb_xor*/
691 0, /*nb_or*/
692 (coercion)float_coerce, /*nb_coerce*/
693 (unaryfunc)float_int, /*nb_int*/
694 (unaryfunc)float_long, /*nb_long*/
695 (unaryfunc)float_float, /*nb_float*/
696 0, /* nb_oct */
697 0, /* nb_hex */
698 0, /* nb_inplace_add */
699 0, /* nb_inplace_subtract */
700 0, /* nb_inplace_multiply */
701 0, /* nb_inplace_divide */
702 0, /* nb_inplace_remainder */
703 0, /* nb_inplace_power */
704 0, /* nb_inplace_lshift */
705 0, /* nb_inplace_rshift */
706 0, /* nb_inplace_and */
707 0, /* nb_inplace_xor */
708 0, /* nb_inplace_or */
709 float_int_div, /* nb_floor_divide */
710 float_div, /* nb_true_divide */
711 0, /* nb_inplace_floor_divide */
712 0, /* nb_inplace_true_divide */
715 PyTypeObject PyFloat_Type = {
716 PyObject_HEAD_INIT(&PyType_Type)
718 "float",
719 sizeof(PyFloatObject),
721 (destructor)float_dealloc, /* tp_dealloc */
722 (printfunc)float_print, /* tp_print */
723 0, /* tp_getattr */
724 0, /* tp_setattr */
725 (cmpfunc)float_compare, /* tp_compare */
726 (reprfunc)float_repr, /* tp_repr */
727 &float_as_number, /* tp_as_number */
728 0, /* tp_as_sequence */
729 0, /* tp_as_mapping */
730 (hashfunc)float_hash, /* tp_hash */
731 0, /* tp_call */
732 (reprfunc)float_str, /* tp_str */
733 PyObject_GenericGetAttr, /* tp_getattro */
734 0, /* tp_setattro */
735 0, /* tp_as_buffer */
736 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */
737 float_doc, /* tp_doc */
738 0, /* tp_traverse */
739 0, /* tp_clear */
740 0, /* tp_richcompare */
741 0, /* tp_weaklistoffset */
742 0, /* tp_iter */
743 0, /* tp_iternext */
744 0, /* tp_methods */
745 0, /* tp_members */
746 0, /* tp_getset */
747 0, /* tp_base */
748 0, /* tp_dict */
749 0, /* tp_descr_get */
750 0, /* tp_descr_set */
751 0, /* tp_dictoffset */
752 0, /* tp_init */
753 0, /* tp_alloc */
754 float_new, /* tp_new */
757 void
758 PyFloat_Fini(void)
760 PyFloatObject *p;
761 PyFloatBlock *list, *next;
762 int i;
763 int bc, bf; /* block count, number of freed blocks */
764 int frem, fsum; /* remaining unfreed floats per block, total */
766 bc = 0;
767 bf = 0;
768 fsum = 0;
769 list = block_list;
770 block_list = NULL;
771 free_list = NULL;
772 while (list != NULL) {
773 bc++;
774 frem = 0;
775 for (i = 0, p = &list->objects[0];
776 i < N_FLOATOBJECTS;
777 i++, p++) {
778 if (PyFloat_Check(p) && p->ob_refcnt != 0)
779 frem++;
781 next = list->next;
782 if (frem) {
783 list->next = block_list;
784 block_list = list;
785 for (i = 0, p = &list->objects[0];
786 i < N_FLOATOBJECTS;
787 i++, p++) {
788 if (!PyFloat_Check(p) || p->ob_refcnt == 0) {
789 p->ob_type = (struct _typeobject *)
790 free_list;
791 free_list = p;
795 else {
796 PyMem_FREE(list); /* XXX PyObject_FREE ??? */
797 bf++;
799 fsum += frem;
800 list = next;
802 if (!Py_VerboseFlag)
803 return;
804 fprintf(stderr, "# cleanup floats");
805 if (!fsum) {
806 fprintf(stderr, "\n");
808 else {
809 fprintf(stderr,
810 ": %d unfreed float%s in %d out of %d block%s\n",
811 fsum, fsum == 1 ? "" : "s",
812 bc - bf, bc, bc == 1 ? "" : "s");
814 if (Py_VerboseFlag > 1) {
815 list = block_list;
816 while (list != NULL) {
817 for (i = 0, p = &list->objects[0];
818 i < N_FLOATOBJECTS;
819 i++, p++) {
820 if (PyFloat_Check(p) && p->ob_refcnt != 0) {
821 char buf[100];
822 PyFloat_AsString(buf, p);
823 fprintf(stderr,
824 "# <float at %p, refcnt=%d, val=%s>\n",
825 p, p->ob_refcnt, buf);
828 list = list->next;