Bugs item #789159, was opened at 2003-08-15 03:39 Message generated for change (Comment added) made by nnorwitz You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=789159&group_id=5470
Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: Python Interpreter Core Group: Python 2.2.3 >Status: Closed >Resolution: Out of Date Priority: 5 Submitted By: Nick Maclaren (nmm1) Assigned to: Nobody/Anonymous (nobody) Summary: Minor floatobject.c bug Initial Comment: The following is a previously reported bug that got only half fixed. The bug was closed before I could respond that the fix was incomplete; here is a complete fix. The failure is when overflow checking is enabled on integers, as is good programming practice and permitted by the C standard. It could also cause wrong answers if overflow is mishandled (as is also permitted and can happen). *** ./Objects/floatobject.c.org Tue Jan 28 19:40:35 2003 --- ./Objects/floatobject.c Tue Jun 3 13:02:48 2003 *************** *** 659,667 **** to long may yield gibberish in either case. What really matters is whether converting back to double again reproduces what we started with. */ ! aslong = (long)wholepart; ! if ((double)aslong == wholepart) ! return PyInt_FromLong(aslong); PyErr_SetString(PyExc_OverflowError, "float too large to convert"); return NULL; } --- 659,669 ---- to long may yield gibberish in either case. What really matters is whether converting back to double again reproduces what we started with. */ ! if (wholepart > LONG_MIN-1.0 && wholepart < LONG_MAX+1.0) { ! aslong = (long)wholepart; ! if ((double)aslong == wholepart) ! return PyInt_FromLong(aslong); ! } PyErr_SetString(PyExc_OverflowError, "float too large to convert"); return NULL; } Regards, Nick Maclaren, University of Cambridge Computing Service, New Museums Site, Pembroke Street, Cambridge CB2 3QH, England. Email: [EMAIL PROTECTED] Tel.: +44 1223 334761 Fax: +44 1223 334679 ---------------------------------------------------------------------- >Comment By: Neal Norwitz (nnorwitz) Date: 2006-10-07 15:54 Message: Logged In: YES user_id=33168 The code is out of date. It looks like the problem has been addressed. Please provide an updated patch in a new report if this is not the case. ---------------------------------------------------------------------- Comment By: Nick Maclaren (nmm1) Date: 2003-08-15 08:08 Message: Logged In: YES user_id=652073 Thanks for the remark about closing. I tried to append, but Sourceforge wouldn't let me. It is all a while ago now, though. Heck. I remember the discussion. That has problems when rounding gets in the way. The following is an improved fix and SHOULD work on all machines, past, present and future that support standard C and used a power of two base floating-point (or base 10, actually): *** floatobject.c.org Tue Jan 28 19:40:35 2003 --- floatobject.c Fri Aug 15 15:22:48 2003 *************** *** 645,667 **** { double x = PyFloat_AsDouble(v); double wholepart; /* integral portion of x, rounded toward 0 */ ! long aslong; /* (long)wholepart */ (void)modf(x, &wholepart); - #ifdef RISCOS - /* conversion from floating to integral type would raise exception */ - if (wholepart>LONG_MAX || wholepart<LONG_MIN) { - PyErr_SetString(PyExc_OverflowError, "float too large to convert"); - return NULL; - } - #endif /* doubles may have more bits than longs, or vice versa; and casting to long may yield gibberish in either case. What really matters is whether converting back to double again reproduces what we ! started with. */ ! aslong = (long)wholepart; ! if ((double)aslong == wholepart) ! return PyInt_FromLong(aslong); PyErr_SetString(PyExc_OverflowError, "float too large to convert"); return NULL; } --- 645,675 ---- { double x = PyFloat_AsDouble(v); double wholepart; /* integral portion of x, rounded toward 0 */ ! long aslong, z; /* (long)wholepart */ ! int i, j, k; (void)modf(x, &wholepart); /* doubles may have more bits than longs, or vice versa; and casting to long may yield gibberish in either case. What really matters is whether converting back to double again reproduces what we ! started with. And remember that exceptions can always occur. */ ! if (wholepart > LONG_MIN/2 && wholepart < LONG_MAX/2) ! x = 0.0; ! else { ! k = (x >= 0.0); ! x = wholepart; ! for (i = (sizeof(long)*CHAR_BIT-1)/16; i >= 0; --i) { ! z = LONG_MAX; ! for (j = 0; j < i; ++j) z >>= 16; ! x -= (k ? 1.0 : -1.0)*ldexp(z&0xffff,16*i); ! } ! if (! k) x = (LONG_MAX+LONG_MIN)-x; ! } ! if (x <= 0.0) { ! aslong = (long)wholepart; ! if ((double)aslong == wholepart) ! return PyInt_FromLong(aslong); ! } PyErr_SetString(PyExc_OverflowError, "float too large to convert"); return NULL; } I have tested it, but don't know the internals well enough to test it exhaustively. ---------------------------------------------------------------------- Comment By: Neal Norwitz (nnorwitz) Date: 2003-08-15 05:44 Message: Logged In: YES user_id=33168 Nick, if we do close a bug, you can still make comments and we'll see it. Thanks. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=105470&aid=789159&group_id=5470 _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com