]> granicus.if.org Git - python/commitdiff
Get float() to be more portable across platforms. Disable hex strings.
authorNeal Norwitz <nnorwitz@gmail.com>
Sun, 18 Dec 2005 05:03:17 +0000 (05:03 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Sun, 18 Dec 2005 05:03:17 +0000 (05:03 +0000)
Lib/test/test_builtin.py
Misc/NEWS
Python/pystrtod.c

index c8a4822c7f5374c5233130343fb3b142fead9244..62489729a05a06b2c3c8f8b6ed7fd674c5ccc026 100644 (file)
@@ -545,6 +545,8 @@ class BuiltinTest(unittest.TestCase):
         self.assertEqual(float(314), 314.0)
         self.assertEqual(float(314L), 314.0)
         self.assertEqual(float("  3.14  "), 3.14)
+        self.assertRaises(ValueError, float, "  0x3.1  ")
+        self.assertRaises(ValueError, float, "  -0x3.p-1  ")
         if have_unicode:
             self.assertEqual(float(unicode("  3.14  ")), 3.14)
             self.assertEqual(float(unicode("  \u0663.\u0661\u0664  ",'raw-unicode-escape')), 3.14)
@@ -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("  0x3.1  "), 3.0625)
-            self.assertEqual(float("  -0x3.p-1  "), -1.5)
+            self.assertRaises(ValueError, float, "  0x3.1  ")
+            self.assertRaises(ValueError, float, "  -0x3.p-1  ")
             self.assertEqual(float("  25.e-1  "), 2.5)
             self.assertEqual(fcmp(float("  .25e-1  "), .025), 0)
         finally:
index 8b79fb6ce5c25e579218bd7433aced24f8b55e55..1db35f44b90d33b510c4a364608a1828d1bbeb34 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
 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
   function Py_GetBuildNumber().  New attribute sys.build_number.  Build number
   is now displayed in interactive prompt banner.
index ab2579982edc1ee159774fa1d05eefb2ee547deb..19f25dab97d5690119cde3374d4c6ef7f08aeb91 100644 (file)
@@ -38,8 +38,7 @@
  * Return value: the #gdouble value.
  **/
 double
-PyOS_ascii_strtod(const char  *nptr, 
-           char       **endptr)
+PyOS_ascii_strtod(const char *nptr, char **endptr)
 {
        char *fail_pos;
        double val;
@@ -49,7 +48,6 @@ PyOS_ascii_strtod(const char  *nptr,
        const char *p, *decimal_point_pos;
        const char *end = NULL; /* Silence gcc */
 
-/*     g_return_val_if_fail (nptr != NULL, 0); */
        assert(nptr != NULL);
 
        fail_pos = NULL;
@@ -73,64 +71,36 @@ PyOS_ascii_strtod(const char  *nptr,
                if (*p == '+' || *p == '-')
                        p++;
 
-               if (p[0] == '0' && 
-                   (p[1] == 'x' || p[1] == 'X'))
+               while (ISDIGIT(*p))
+                       p++;
+
+               if (*p == '.')
                {
-                       p += 2;
-                         /* HEX - find the (optional) decimal point */
+                       decimal_point_pos = p++;
 
-                       while (ISXDIGIT(*p))
+                       while (ISDIGIT(*p))
                                p++;
 
-                       if (*p == '.')
-                       {
-                               decimal_point_pos = p++;
-
-                               while (ISXDIGIT(*p))
-                                       p++;
-
-                               if (*p == 'p' || *p == 'P')
-                                       p++;
-                               if (*p == '+' || *p == '-')
-                                       p++;
-                               while (ISDIGIT(*p))
-                                       p++;
-                               end = p;
-                       }
-               }
-               else
-               {
+                       if (*p == 'e' || *p == 'E')
+                               p++;
+                       if (*p == '+' || *p == '-')
+                               p++;
                        while (ISDIGIT(*p))
                                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;
-                       }
+                       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
-            and underflows */
+       /* Set errno to zero, so that we can distinguish zero results
+          and underflows */
        errno = 0;
 
        if (decimal_point_pos)
        {
                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);
 
                c = copy;
@@ -155,8 +125,15 @@ PyOS_ascii_strtod(const char  *nptr,
                free(copy);
 
        }
-       else
-               val = strtod(nptr, &fail_pos);
+       else {
+               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)
                *endptr = fail_pos;