[pypy-svn] pypy fast-forward: Fix the test, in a way that prepares the path for integration with dtoa.c

amauryfa commits-noreply at bitbucket.org
Tue Jan 4 11:39:25 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: fast-forward
Changeset: r40374:14043b3b5c16
Date: 2011-01-04 11:38 +0100
http://bitbucket.org/pypy/pypy/changeset/14043b3b5c16/

Log:	Fix the test, in a way that prepares the path for integration with
	dtoa.c

diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -566,6 +566,7 @@
 DIST_NAN      = 2
 DIST_INFINITY = 3
 
+# Equivalent to CPython's PyOS_double_to_string
 def _formatd(x, code, precision, flags):
     "NOT_RPYTHON"
     if flags & DTSF_ALT:

diff --git a/pypy/rpython/module/ll_strtod.py b/pypy/rpython/module/ll_strtod.py
--- a/pypy/rpython/module/ll_strtod.py
+++ b/pypy/rpython/module/ll_strtod.py
@@ -26,13 +26,38 @@
         ll_strtod = self.llexternal('LL_strtod_formatd',
                                     [rffi.DOUBLE, rffi.CHAR, rffi.INT], rffi.CCHARP,
                                     sandboxsafe=True, threadsafe=False)
-        
+
+        # Like PyOS_double_to_string(), when PY_NO_SHORT_FLOAT_REPR is defined
         def llimpl(x, code, precision, flags):
+            upper = False
             if code == 'r':
                 code = 'g'
                 precision = 17
+            elif code == 'E':
+                code = 'e'
+                upper = True
+            elif code == 'F':
+                code = 'f'
+                upper = True
+            elif code == 'G':
+                code = 'g'
+                upper = True
+
             res = ll_strtod(x, code, precision)
-            return rffi.charp2str(res)
+            s = rffi.charp2str(res)
+
+            if flags & rarithmetic.DTSF_ADD_DOT_0:
+                s = ensure_decimal_point(s, precision)
+
+            # Add sign when requested
+            if flags & rarithmetic.DTSF_SIGN and s[0] != '-':
+                s = '+' + s
+
+            # Convert to upper case
+            if upper:
+                s = s.upper()
+
+            return s
 
         def oofakeimpl(x, code, precision, flags):
             return ootype.oostring(rarithmetic.formatd(x, code, precision, flags), -1)
@@ -61,3 +86,28 @@
         return extdef([str, str, str, str], float,
                       'll_strtod.ll_strtod_parts_to_float', llimpl=llimpl,
                       oofakeimpl=oofakeimpl, sandboxsafe=True)
+
+def ensure_decimal_point(s, precision):
+    # make sure we have at least one character after the decimal point (and
+    # make sure we have a decimal point); also switch to exponential notation
+    # in some edge cases where the extra character would produce more
+    # significant digits that we really want.
+
+    pos = s.find('.')
+    if pos >= 0:
+        if pos + 1 < len(s) and s[pos + 1].isdigit():
+            # Nothing to do, we already have a decimal point
+            # and a digit after it
+            pass
+        else:
+            # Normally not used
+            s += '0'
+    else:
+        pos = s.find('e')
+        if pos >= 0:
+            # Don't add ".0" if we have an exponent
+            pass
+        else:
+            s += '.0'
+
+    return s

diff --git a/pypy/translator/c/src/ll_strtod.h b/pypy/translator/c/src/ll_strtod.h
--- a/pypy/translator/c/src/ll_strtod.h
+++ b/pypy/translator/c/src/ll_strtod.h
@@ -89,7 +89,8 @@
 char* LL_strtod_formatd(double x, char code, int precision) {
 	int res;
 	const char* fmt;
-        if (code == 'f') fmt = "%.*f";
+        if (code == 'e') fmt = "%.*e";
+        else if (code == 'f') fmt = "%.*f";
         else if (code == 'g') fmt = "%.*g";
         else {
             strcpy(buffer, "??.?"); /* should not occur */


More information about the Pypy-commit mailing list