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

Reply via email to