Commit e7214a13 authored by Neal Norwitz's avatar Neal Norwitz

Get float() to be more portable across platforms. Disable hex strings.

parent 87b801cc
...@@ -545,6 +545,8 @@ class BuiltinTest(unittest.TestCase): ...@@ -545,6 +545,8 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(float(314), 314.0) self.assertEqual(float(314), 314.0)
self.assertEqual(float(314L), 314.0) self.assertEqual(float(314L), 314.0)
self.assertEqual(float(" 3.14 "), 3.14) self.assertEqual(float(" 3.14 "), 3.14)
self.assertRaises(ValueError, float, " 0x3.1 ")
self.assertRaises(ValueError, float, " -0x3.p-1 ")
if have_unicode: if have_unicode:
self.assertEqual(float(unicode(" 3.14 ")), 3.14) self.assertEqual(float(unicode(" 3.14 ")), 3.14)
self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14) self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14)
...@@ -572,8 +574,8 @@ class BuiltinTest(unittest.TestCase): ...@@ -572,8 +574,8 @@ class BuiltinTest(unittest.TestCase):
self.assertEqual(float(" 3,14 "), 3.14) self.assertEqual(float(" 3,14 "), 3.14)
self.assertEqual(float(" +3,14 "), 3.14) self.assertEqual(float(" +3,14 "), 3.14)
self.assertEqual(float(" -3,14 "), -3.14) self.assertEqual(float(" -3,14 "), -3.14)
self.assertEqual(float(" 0x3.1 "), 3.0625) self.assertRaises(ValueError, float, " 0x3.1 ")
self.assertEqual(float(" -0x3.p-1 "), -1.5) self.assertRaises(ValueError, float, " -0x3.p-1 ")
self.assertEqual(float(" 25.e-1 "), 2.5) self.assertEqual(float(" 25.e-1 "), 2.5)
self.assertEqual(fcmp(float(" .25e-1 "), .025), 0) self.assertEqual(fcmp(float(" .25e-1 "), .025), 0)
finally: finally:
......
...@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1? ...@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Support for converting hex strings to floats no longer works.
This was not portable. float('0x3') now raises a ValueError.
- Patch #1382163: Expose Subversion revision number to Python. New C API - Patch #1382163: Expose Subversion revision number to Python. New C API
function Py_GetBuildNumber(). New attribute sys.build_number. Build number function Py_GetBuildNumber(). New attribute sys.build_number. Build number
is now displayed in interactive prompt banner. is now displayed in interactive prompt banner.
......
...@@ -38,8 +38,7 @@ ...@@ -38,8 +38,7 @@
* Return value: the #gdouble value. * Return value: the #gdouble value.
**/ **/
double double
PyOS_ascii_strtod(const char *nptr, PyOS_ascii_strtod(const char *nptr, char **endptr)
char **endptr)
{ {
char *fail_pos; char *fail_pos;
double val; double val;
...@@ -49,7 +48,6 @@ PyOS_ascii_strtod(const char *nptr, ...@@ -49,7 +48,6 @@ PyOS_ascii_strtod(const char *nptr,
const char *p, *decimal_point_pos; const char *p, *decimal_point_pos;
const char *end = NULL; /* Silence gcc */ const char *end = NULL; /* Silence gcc */
/* g_return_val_if_fail (nptr != NULL, 0); */
assert(nptr != NULL); assert(nptr != NULL);
fail_pos = NULL; fail_pos = NULL;
...@@ -73,64 +71,36 @@ PyOS_ascii_strtod(const char *nptr, ...@@ -73,64 +71,36 @@ PyOS_ascii_strtod(const char *nptr,
if (*p == '+' || *p == '-') if (*p == '+' || *p == '-')
p++; p++;
if (p[0] == '0' && while (ISDIGIT(*p))
(p[1] == 'x' || p[1] == 'X')) p++;
if (*p == '.')
{ {
p += 2; decimal_point_pos = p++;
/* HEX - find the (optional) decimal point */
while (ISXDIGIT(*p)) while (ISDIGIT(*p))
p++; p++;
if (*p == '.') if (*p == 'e' || *p == 'E')
{ p++;
decimal_point_pos = p++; if (*p == '+' || *p == '-')
p++;
while (ISXDIGIT(*p))
p++;
if (*p == 'p' || *p == 'P')
p++;
if (*p == '+' || *p == '-')
p++;
while (ISDIGIT(*p))
p++;
end = p;
}
}
else
{
while (ISDIGIT(*p)) while (ISDIGIT(*p))
p++; p++;
end = p;
if (*p == '.')
{
decimal_point_pos = p++;
while (ISDIGIT(*p))
p++;
if (*p == 'e' || *p == 'E')
p++;
if (*p == '+' || *p == '-')
p++;
while (ISDIGIT(*p))
p++;
end = p;
}
} }
/* For the other cases, we need not convert the decimal point */ /* For the other cases, we need not convert the decimal point */
} }
/* Set errno to zero, so that we can distinguish zero results /* Set errno to zero, so that we can distinguish zero results
and underflows */ and underflows */
errno = 0; errno = 0;
if (decimal_point_pos) if (decimal_point_pos)
{ {
char *copy, *c; char *copy, *c;
/* We need to convert the '.' to the locale specific decimal point */ /* We need to convert the '.' to the locale specific decimal point */
copy = malloc(end - nptr + 1 + decimal_point_len); copy = malloc(end - nptr + 1 + decimal_point_len);
c = copy; c = copy;
...@@ -155,8 +125,15 @@ PyOS_ascii_strtod(const char *nptr, ...@@ -155,8 +125,15 @@ PyOS_ascii_strtod(const char *nptr,
free(copy); free(copy);
} }
else else {
val = strtod(nptr, &fail_pos); unsigned i = 0;
if (nptr[i] == '-')
i++;
if (nptr[i] == '0' && (nptr[i+1] == 'x' || nptr[i+1] == 'X'))
fail_pos = nptr;
else
val = strtod(nptr, &fail_pos);
}
if (endptr) if (endptr)
*endptr = fail_pos; *endptr = fail_pos;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment