[Python-checkins] r71584 - in python/branches/py3k-short-float-repr: Include/pyport.h Python/pystrtod.c

mark.dickinson python-checkins at python.org
Mon Apr 13 19:20:45 CEST 2009


Author: mark.dickinson
Date: Mon Apr 13 19:20:45 2009
New Revision: 71584

Log:
Force 53-bit precision for calls to _Py_dg_strtod and _Py_dg_dtoa


Modified:
   python/branches/py3k-short-float-repr/Include/pyport.h
   python/branches/py3k-short-float-repr/Python/pystrtod.c

Modified: python/branches/py3k-short-float-repr/Include/pyport.h
==============================================================================
--- python/branches/py3k-short-float-repr/Include/pyport.h	(original)
+++ python/branches/py3k-short-float-repr/Include/pyport.h	Mon Apr 13 19:20:45 2009
@@ -465,6 +465,29 @@
 			errno = 0;					\
 	} while(0)
 
+/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c require that
+   the FPU is using 53-bit precision.  Here are macros that force this.  See
+   Python/pystrtod.c for an example of their use. */
+
+#ifdef USING_X87_FPU
+#define _Py_SET_53BIT_PRECISION_HEADER				\
+	unsigned short old_387controlword, new_387controlword
+#define _Py_SET_53BIT_PRECISION_START					\
+	do {								\
+		old_387controlword = _Py_get_387controlword();		\
+		new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \
+		if (new_387controlword != old_387controlword)		\
+			_Py_set_387controlword(new_387controlword);	\
+	} while (0)
+#define _Py_SET_53BIT_PRECISION_END				\
+	if (new_387controlword != old_387controlword)		\
+		_Py_set_387controlword(old_387controlword)
+#else
+#define _Py_SET_53BIT_PRECISION_HEADER
+#define _Py_SET_53BIT_PRECISION_START
+#define _Py_SET_53BIT_PRECISION_END
+#endif
+
 /* Py_DEPRECATED(version)
  * Declare a variable, type, or function deprecated.
  * Usage:

Modified: python/branches/py3k-short-float-repr/Python/pystrtod.c
==============================================================================
--- python/branches/py3k-short-float-repr/Python/pystrtod.c	(original)
+++ python/branches/py3k-short-float-repr/Python/pystrtod.c	Mon Apr 13 19:20:45 2009
@@ -40,11 +40,20 @@
 double
 PyOS_ascii_strtod(const char *nptr, char **endptr)
 {
+	double result;
+	_Py_SET_53BIT_PRECISION_HEADER;
+
 	assert(nptr != NULL);
 	/* Set errno to zero, so that we can distinguish zero results
 	   and underflows */
 	errno = 0;
-	return _Py_dg_strtod(nptr, endptr);
+
+	_Py_SET_53BIT_PRECISION_START;
+	result = _Py_dg_strtod(nptr, endptr);
+	_Py_SET_53BIT_PRECISION_END;
+
+	return result;
+
 }
 
 double
@@ -561,11 +570,15 @@
 	char *digits, *digits_end;
 	int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0;
 	Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end;
+	_Py_SET_53BIT_PRECISION_HEADER;
 
 	/* _Py_dg_dtoa returns a digit string (no decimal point or exponent).
 	   Must be matched by a call to _Py_dg_freedtoa. */
+	_Py_SET_53BIT_PRECISION_START;
 	digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign,
 			     &digits_end);
+	_Py_SET_53BIT_PRECISION_END;
+
 	decpt = (Py_ssize_t)decpt_as_int;
 	if (digits == NULL) {
 		/* The only failure mode is no memory. */


More information about the Python-checkins mailing list