]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
SF bug #422177: Results from .pyc differs from .py
authorTim Peters <tim.peters@gmail.com>
Tue, 8 May 2001 15:19:57 +0000 (15:19 +0000)
committerTim Peters <tim.peters@gmail.com>
Tue, 8 May 2001 15:19:57 +0000 (15:19 +0000)
Store floats and doubles to full precision in marshal.
Test that floats read from .pyc/.pyo closely match those read from .py.
Declare PyFloat_AsString() in floatobject header file.
Add new PyFloat_AsReprString() API function.
Document the functions declared in floatobject.h.

Include/floatobject.h
Lib/test/test_import.py
Objects/floatobject.c
Python/marshal.c

index 1d0b50a620dbae1aad1d019f7a5503bc7197f275..6e36a2f318715581508d5a4027fe7e1ee9bc8412 100644 (file)
@@ -20,13 +20,32 @@ extern DL_IMPORT(PyTypeObject) PyFloat_Type;
 
 #define PyFloat_Check(op) ((op)->ob_type == &PyFloat_Type)
 
-extern DL_IMPORT(PyObject *) PyFloat_FromString(PyObject*, char**);
+/* Return Python float from string PyObject.  Second argument ignored on
+   input, and, if non-NULL, NULL is stored into *junk (this tried to serve a
+   purpose once but can't be made to work as intended). */
+extern DL_IMPORT(PyObject *) PyFloat_FromString(PyObject*, char** junk);
+
+/* Return Python float from C double. */
 extern DL_IMPORT(PyObject *) PyFloat_FromDouble(double);
-extern DL_IMPORT(double) PyFloat_AsDouble(PyObject *);
 
-/* Macro, trading safety for speed */
+/* Extract C double from Python float.  The macro version trades safety for
+   speed. */
+extern DL_IMPORT(double) PyFloat_AsDouble(PyObject *);
 #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
 
+/* Write repr(v) into the char buffer argument, followed by null byte.  The
+   buffer must be "big enough"; >= 100 is very safe.
+   PyFloat_AsReprString(buf, x) strives to print enough digits so that
+   PyFloat_FromString(buf) then reproduces x exactly. */
+extern DL_IMPORT(void) PyFloat_AsReprString(char*, PyFloatObject *v);
+
+/* Write str(v) into the char buffer argument, followed by null byte.  The
+   buffer must be "big enough"; >= 100 is very safe.  Note that it's
+   unusual to be able to get back the float you started with from
+   PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to
+   preserve precision across conversions. */
+extern DL_IMPORT(void) PyFloat_AsString(char*, PyFloatObject *v);
+
 #ifdef __cplusplus
 }
 #endif
index a151defa21ca8c93b1df6884eea814aae189e3c7..5419b5af7f7bae0afdc41c6ba6b8d1a73e772f1f 100644 (file)
@@ -13,6 +13,9 @@ except ImportError:
 else:
     raise TestFailed("import of RAnDoM should have failed (case mismatch)")
 
+# Another brief digression to test the accuracy of manifest float constants.
+import double_const  # don't blink -- that *was* the test
+
 sys.path.insert(0, os.curdir)
 
 source = TESTFN + ".py"
index b129798033173f370ad1b07193c2789adc5f8d62..2f17d02837e559685c0272946301e8a2d9a3b5d5 100644 (file)
@@ -311,6 +311,12 @@ PyFloat_AsString(char *buf, PyFloatObject *v)
        PyFloat_AsStringEx(buf, v, PREC_STR);
 }
 
+void
+PyFloat_AsReprString(char *buf, PyFloatObject *v)
+{
+       PyFloat_AsStringEx(buf, v, PREC_REPR);
+}
+
 /* ARGSUSED */
 static int
 float_print(PyFloatObject *v, FILE *fp, int flags)
index 120c3fade67a8f8dc2dce81edf6f8ee539319fcb..7cd84f684f14f2f9cb4208327eacf7df7abea592 100644 (file)
@@ -149,9 +149,8 @@ w_object(PyObject *v, WFILE *p)
                        w_short(ob->ob_digit[i], p);
        }
        else if (PyFloat_Check(v)) {
-               extern void PyFloat_AsString(char *, PyFloatObject *);
                char buf[256]; /* Plenty to format any double */
-               PyFloat_AsString(buf, (PyFloatObject *)v);
+               PyFloat_AsReprString(buf, (PyFloatObject *)v);
                n = strlen(buf);
                w_byte(TYPE_FLOAT, p);
                w_byte(n, p);
@@ -159,20 +158,19 @@ w_object(PyObject *v, WFILE *p)
        }
 #ifndef WITHOUT_COMPLEX
        else if (PyComplex_Check(v)) {
-               extern void PyFloat_AsString(char *, PyFloatObject *);
                char buf[256]; /* Plenty to format any double */
                PyFloatObject *temp;
                w_byte(TYPE_COMPLEX, p);
                temp = (PyFloatObject*)PyFloat_FromDouble(
                        PyComplex_RealAsDouble(v));
-               PyFloat_AsString(buf, temp);
+               PyFloat_AsReprString(buf, temp);
                Py_DECREF(temp);
                n = strlen(buf);
                w_byte(n, p);
                w_string(buf, n, p);
                temp = (PyFloatObject*)PyFloat_FromDouble(
                        PyComplex_ImagAsDouble(v));
-               PyFloat_AsString(buf, temp);
+               PyFloat_AsReprString(buf, temp);
                Py_DECREF(temp);
                n = strlen(buf);
                w_byte(n, p);