Issue789159
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2003-08-15 10:39 by nmm1, last changed 2022-04-10 16:10 by admin. This issue is now closed.
Messages (4) | |||
---|---|---|---|
msg17778 - (view) | Author: Nick Maclaren (nmm1) | Date: 2003-08-15 10:39 | |
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: nmm1@cam.ac.uk Tel.: +44 1223 334761 Fax: +44 1223 334679 |
|||
msg17779 - (view) | Author: Neal Norwitz (nnorwitz) * | Date: 2003-08-15 12:44 | |
Logged In: YES user_id=33168 Nick, if we do close a bug, you can still make comments and we'll see it. Thanks. |
|||
msg17780 - (view) | Author: Nick Maclaren (nmm1) | Date: 2003-08-15 15:08 | |
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. |
|||
msg17781 - (view) | Author: Neal Norwitz (nnorwitz) * | Date: 2006-10-07 22:54 | |
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. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:10:39 | admin | set | github: 39068 |
2003-08-15 10:39:13 | nmm1 | create |