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.

classification
Title: -1e-1000 converted incorrectly
Type: Stage:
Components: Versions: Python 3.0, Python 2.6, Python 2.5
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: Nosy List: christian.heimes, gvanrossum, mark.dickinson
Priority: normal Keywords: patch

Created on 2008-01-03 00:04 by gvanrossum, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
pystrtod.patch mark.dickinson, 2008-01-03 19:45
Messages (9)
msg59113 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-01-03 00:04
Since 1e-1000 == 0.0 (on an IEEE-754 platform anyway), I would expect
-1e-1000 to be -0.0.  But it does not appear that way:

>>> 1e-1000
0.0
>>> -0.0
-0.0
>>> -1e-1000
0.0

However (correctly):

>>> (-1.0) * 1e-1000
-0.0
>>> -(1e-1000)
-0.0

I suspect the optimization for -x where x is a float literal is
incorrectly triggering here.
msg59114 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-01-03 00:07
BTW this was on x86 Linux.  On x86 OSX (10.4, Tiger) it works correctly:

>>> -1e-1000
-0.0
msg59120 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-01-03 03:05
Tracing the calls through ast_for_factor -> ast_for_atom -> parsenumber -> PyOS_ascii_atof -> 
PyOS_ascii_strtod -> strtod, it looks as though the cause is simply that strtod behaves differently on 
the two platforms.  I get that the following code:

#include <stdio.h>
#include <stdlib.h>

int main() {
  char *fail_pos;
  double x;
  
  x = strtod("-1e-1000", &fail_pos);
  printf("Result: %f\n", x);

  return 0;
}

produces 0.000000 on Linux (SuSE 10.2) and -0.000000 on OS X 10.4.11.
msg59132 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008-01-03 15:25
I think we have found a bug in glibc's math code. I'm hanging around in
#glibc and see if I can get an opinion on the matter.
msg59133 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2008-01-03 15:29
On Windows -1E-1000 returns 0.0, too. We may need to fix it in your own
code and set the sign bit ourself.
msg59135 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-01-03 16:05
Presumably  float('-1e-1000') should also give -0.  (?)
If so, then it looks as though the fix ought to go in PyOS_ascii_strtod: 
one obvious possibility would be to replace any leading '-' sign by a '+' 
sign before calling the system strtod, then negate the result afterwards.
msg59148 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2008-01-03 19:45
Here's a possible fix for this issue;  it parses a number by first stripping leading 
whitespace and any sign, then passing the remaining string to the system strtod.

This patch also fixes another bug in pystrtod.c, where ValueError is not raised on a 
hex float with a leading + sign:

>>> float('0x3')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for float(): 0x3
>>> float('+0x3')  # expect ValueError
3.0
msg59273 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-01-05 01:02
Committed revision 59725.

Thanks for the fix, Mark!  This issue is a great example of how our
development process works well.

I propose not to backport this to 2.5.2, it's a rather minor issue and
who knows what user code might depend on the existing buggy behavior...
msg59274 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2008-01-05 01:02
PS. I reformatted some long lines in the patch.  In general, I like to
keep all lines < 80 chars, in both C and Python code.
History
Date User Action Args
2022-04-11 14:56:29adminsetgithub: 46066
2008-01-05 01:02:38gvanrossumsetmessages: + msg59274
2008-01-05 01:02:03gvanrossumsetstatus: open -> closed
priority: normal
messages: + msg59273
resolution: accepted
keywords: + patch
2008-01-03 19:45:59mark.dickinsonsetfiles: + pystrtod.patch
messages: + msg59148
2008-01-03 16:05:41mark.dickinsonsetmessages: + msg59135
2008-01-03 15:29:59christian.heimessetmessages: + msg59133
2008-01-03 15:25:59christian.heimessetnosy: + christian.heimes
messages: + msg59132
2008-01-03 03:05:28mark.dickinsonsetnosy: + mark.dickinson
messages: + msg59120
2008-01-03 00:07:48gvanrossumsetmessages: + msg59114
2008-01-03 00:04:55gvanrossumcreate