[Python-checkins] r71047 - in python/branches/py3k-short-float-repr: Include/pystrtod.h Modules/_pickle.c Objects/complexobject.c Objects/floatobject.c Objects/unicodeobject.c Python/marshal.c Python/pystrtod.c

eric.smith python-checkins at python.org
Thu Apr 2 16:06:35 CEST 2009


Author: eric.smith
Date: Thu Apr 2 16:06:34 2009
New Revision: 71047
Log:
Removed explicit mode parameter, now derive the mode from the format_code. Added special format_code 'r' for use with repr.
Many tests still fail, this is just a checkpoint so Mark and I can synchronize.
Modified:
 python/branches/py3k-short-float-repr/Include/pystrtod.h
 python/branches/py3k-short-float-repr/Modules/_pickle.c
 python/branches/py3k-short-float-repr/Objects/complexobject.c
 python/branches/py3k-short-float-repr/Objects/floatobject.c
 python/branches/py3k-short-float-repr/Objects/unicodeobject.c
 python/branches/py3k-short-float-repr/Python/marshal.c
 python/branches/py3k-short-float-repr/Python/pystrtod.c
Modified: python/branches/py3k-short-float-repr/Include/pystrtod.h
==============================================================================
--- python/branches/py3k-short-float-repr/Include/pystrtod.h	(original)
+++ python/branches/py3k-short-float-repr/Include/pystrtod.h	Thu Apr 2 16:06:34 2009
@@ -10,7 +10,6 @@
 PyAPI_FUNC(double) PyOS_ascii_atof(const char *str);
 PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, const char *format, double d);
 PyAPI_FUNC(char *) PyOS_double_to_string(double val,
- int mode,
 char format_code,
 int precision,
 int flags);
Modified: python/branches/py3k-short-float-repr/Modules/_pickle.c
==============================================================================
--- python/branches/py3k-short-float-repr/Modules/_pickle.c	(original)
+++ python/branches/py3k-short-float-repr/Modules/_pickle.c	Thu Apr 2 16:06:34 2009
@@ -1025,7 +1025,7 @@
 if (pickler_write(self, &op, 1) < 0)
 goto done;
 
- buf = PyOS_double_to_string(x, 2, 'g', 17, 0);
+ buf = PyOS_double_to_string(x, 'g', 17, 0);
 if (!buf) {
 PyErr_NoMemory();
 goto done;
Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c
==============================================================================
--- python/branches/py3k-short-float-repr/Objects/complexobject.c	(original)
+++ python/branches/py3k-short-float-repr/Objects/complexobject.c	Thu Apr 2 16:06:34 2009
@@ -339,7 +339,7 @@
 
 
 static PyObject *
-complex_format(PyComplexObject *v, int mode, int precision)
+complex_format(PyComplexObject *v, char format_code, int precision)
 {
 PyObject *result = NULL;
 Py_ssize_t len;
@@ -368,7 +368,8 @@
 im = "-inf*";
 }
 else {
- pim = PyOS_double_to_string(v->cval.imag, mode, 'g', precision, 0);
+ pim = PyOS_double_to_string(v->cval.imag, format_code,
+ precision, 0);
 if (!pim) {
 PyErr_NoMemory();
 goto done;
@@ -387,7 +388,8 @@
 re = "-inf";
 }
 else {
- pre = PyOS_double_to_string(v->cval.real, mode, 'g', precision, 0);
+ pre = PyOS_double_to_string(v->cval.real, format_code,
+ precision, 0);
 if (!pre) {
 PyErr_NoMemory();
 goto done;
@@ -405,8 +407,8 @@
 im = "-inf*";
 }
 else {
- pim = PyOS_double_to_string(v->cval.imag, mode, 'g', precision,
- Py_DTSF_SIGN);
+ pim = PyOS_double_to_string(v->cval.imag, format_code,
+ precision, Py_DTSF_SIGN);
 if (!pim) {
 PyErr_NoMemory();
 goto done;
@@ -436,13 +438,13 @@
 static PyObject *
 complex_repr(PyComplexObject *v)
 {
- return complex_format(v, 0, 0);
+ return complex_format(v, 'r', 0);
 }
 
 static PyObject *
 complex_str(PyComplexObject *v)
 {
- return complex_format(v, 2, PREC_STR);
+ return complex_format(v, 'g', PREC_STR);
 }
 
 static long
Modified: python/branches/py3k-short-float-repr/Objects/floatobject.c
==============================================================================
--- python/branches/py3k-short-float-repr/Objects/floatobject.c	(original)
+++ python/branches/py3k-short-float-repr/Objects/floatobject.c	Thu Apr 2 16:06:34 2009
@@ -365,11 +365,12 @@
 #define PREC_STR	12
 
 static PyObject *
-float_str_or_repr(PyFloatObject *v, int mode, int precision)
+float_str_or_repr(PyFloatObject *v, char format_code, int precision)
 {
 PyObject *result;
 char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
- mode, 'g', precision, Py_DTSF_ADD_DOT_0);
+ format_code, precision,
+ Py_DTSF_ADD_DOT_0);
 if (!buf)
 return PyErr_NoMemory();
 result = PyUnicode_FromString(buf);
@@ -380,13 +381,13 @@
 static PyObject *
 float_repr(PyFloatObject *v)
 {
- return float_str_or_repr(v, 0, 0);
+ return float_str_or_repr(v, 'r', 0);
 }
 
 static PyObject *
 float_str(PyFloatObject *v)
 {
- return float_str_or_repr(v, 2, PREC_STR);
+ return float_str_or_repr(v, 'g', PREC_STR);
 }
 
 /* Comparison is pretty much a nightmare. When comparing float to float,
@@ -1916,7 +1917,7 @@
 				if (PyFloat_CheckExact(p) &&
 				 Py_REFCNT(p) != 0) {
 					char *buf = PyOS_double_to_string(
-						PyFloat_AS_DOUBLE(p), 0, 'g',
+						PyFloat_AS_DOUBLE(p), 'g',
 						0, Py_DTSF_ADD_DOT_0);
 					if (buf) {
 						/* XXX(twouters) cast
Modified: python/branches/py3k-short-float-repr/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k-short-float-repr/Objects/unicodeobject.c	(original)
+++ python/branches/py3k-short-float-repr/Objects/unicodeobject.c	Thu Apr 2 16:06:34 2009
@@ -8844,7 +8844,7 @@
 goto done;
 }
 
- p = PyOS_double_to_string(x, 2, type, prec,
+ p = PyOS_double_to_string(x, type, prec,
 (flags & F_ALT) ? Py_DTSF_ALT : 0);
 len = strlen(p);
 if (len+1 >= buflen) {
Modified: python/branches/py3k-short-float-repr/Python/marshal.c
==============================================================================
--- python/branches/py3k-short-float-repr/Python/marshal.c	(original)
+++ python/branches/py3k-short-float-repr/Python/marshal.c	Thu Apr 2 16:06:34 2009
@@ -237,7 +237,7 @@
 		}
 		else {
 			char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
-				0, 'g', 0, Py_DTSF_ADD_DOT_0);
+				'g', 0, Py_DTSF_ADD_DOT_0);
 			if (!buf)
 return;
 			n = strlen(buf);
@@ -269,7 +269,7 @@
 			char *buf;
 			w_byte(TYPE_COMPLEX, p);
 			buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
-				0, 'g', 0, Py_DTSF_ADD_DOT_0);
+				'g', 0, Py_DTSF_ADD_DOT_0);
 			if (!buf)
 return;
 			n = strlen(buf);
@@ -277,7 +277,7 @@
 			w_string(buf, (int)n, p);
 			PyMem_Free(buf);
 			buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
-				0, 'g', 0, Py_DTSF_ADD_DOT_0);
+				'g', 0, Py_DTSF_ADD_DOT_0);
 			if (!buf)
 return;
 			n = strlen(buf);
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	Thu Apr 2 16:06:34 2009
@@ -524,23 +524,30 @@
 number of significant digits. */
 
 static void
-format_float_short(char *buf, size_t buflen, double d, char format_code,
-		 int mode, int precision, int always_add_sign,
-		 int add_dot_0_if_integer, int use_alt_formatting,
-		 char **float_strings)
+format_float_short(char *buf, Py_ssize_t buflen, double d, char format_code,
+		 int mode, Py_ssize_t precision,
+		 Py_ssize_t n_wanted_digits_after_decimal,
+		 int always_add_sign, int add_dot_0_if_integer,
+		 int use_alt_formatting, char **float_strings)
 {
 	char *digits, *digits_end;
 	int decpt, sign, exp_len;
-	Py_ssize_t digits_len, i;
 	int use_exp = 0;
 	int is_integer = 1; /* is the output produced so far
 				just an integer? */
+	int add_padding = 0;
+	Py_ssize_t n_digits_after_decimal = 0;
+	Py_ssize_t n_digits;
+	Py_ssize_t i;
 
 	/* _Py_dg_dtoa returns a digit string (no decimal point or
 	 exponent) */
 	digits = _Py_dg_dtoa(d, mode, precision, &decpt, &sign, &digits_end);
+	if (!(digits_end != NULL && digits_end > digits)) {
+		printf("%f %p %p %d %c %d\n", d, digits_end, digits, mode, format_code, precision);
+	}
 	assert(digits_end != NULL && digits_end > digits);
-	digits_len = digits_end - digits;
+	n_digits = digits_end - digits;
 
 	if (!isdigit(digits[0])) {
 		/* infinities and nans here; adapt Gay's output,
@@ -565,7 +572,7 @@
 			 something starting with a digit, an 'I', or an
 			 'N' */
 			printf("Help! dtoa returned: %.*s\n",
-			 (int)digits_len, digits);
+			 (int)n_digits, digits);
 			assert(0);
 		}
 		*buf = '0円';
@@ -612,62 +619,60 @@
 		*buf++ = digits[0];
 		*buf++ = '.';
 		is_integer = 0;
-		strncpy(buf, digits+1, digits_len-1);
-		buf += digits_len-1;
+		strncpy(buf, digits + 1, n_digits - 1);
+		buf += n_digits - 1;
 
 	} else {
 		/* use fixed-point notation */
 		if (decpt <= 0) {
-			/* output: 0.00...00dd...dd */
+			/* output: 0.00-00dd-dd */
 			*buf++ = '0';
 			*buf++ = '.';
 			is_integer = 0;
 			for (i = 0; i < -decpt; i++)
 				*buf++ = '0';
-			strncpy(buf, digits, digits_len);
-			buf += digits_len;
+			strncpy(buf, digits, n_digits);
+			buf += n_digits;
+			n_digits_after_decimal = n_digits - decpt;
 		}
-		else if (decpt < digits_len) {
-			/* output: dd...dd.dd...dd */
+		else if (decpt < n_digits) {
+			/* output: dd-dd.dd-dd */
 			strncpy(buf, digits, decpt);
 			buf += decpt;
 			*buf++ = '.';
 			is_integer = 0;
-			strncpy(buf, digits+decpt, digits_len-decpt);
-			buf += digits_len-decpt;
+			strncpy(buf, digits + decpt, n_digits - decpt);
+			buf += n_digits - decpt;
+			n_digits_after_decimal = n_digits - decpt;
 		}
 		else {
-			/* decpt >= digits_len. output: dd...dd00...00.0 */
-			strncpy(buf, digits, digits_len);
-			buf += digits_len;
-			for (i = 0; i < decpt-digits_len; i++)
+			/* decpt >= n_digits. output: dd-dd00-00.0 */
+			strncpy(buf, digits, n_digits);
+			buf += n_digits;
+			for (i = 0; i < decpt - n_digits; i++)
 				*buf++ = '0';
 			*buf++ = '.';
 			is_integer = 0;
+			n_digits_after_decimal = decpt - n_digits;
 		}
 	}
 
-	/* Add trailing non-significant zeros for non-mode 0 and non-code g, unless doing alt formatting */
-	int pad = 0;
+	/* Add trailing non-significant zeros for non-mode 0 and non-code g,
+	 unless doing alt formatting */
 	if (mode != 0) {
 		if (format_code == 'g') {
 			if (use_alt_formatting)
-				pad = 1;
+				add_padding = 1;
 		}
 		else
-			pad = 1;
+			add_padding = 1;
 	}
 
-	if (pad) {
-		Py_ssize_t nzeros = precision - digits_len;
-
-		/* It should never be the case that nzeros is negative, but
-		 check anyway. And while we're at it, skip 0 zeros. */
-		if (nzeros > 0) {
-			for (i = 0; i < nzeros; i++)
-				*buf++ = '0';
-		}
-	}
+	/* It should never be the case that n_trailing_zeros is negative, but
+	 if so this loop executes zero times. */
+	if (add_padding)
+		for (i = n_digits_after_decimal; i < n_wanted_digits_after_decimal; i++)
+			*buf++ = '0';
 
 	/* See if we want to have the trailing decimal or not */
 	if (format_code == 'g' && buf[-1] == '.') {
@@ -694,7 +699,6 @@
 
 
 PyAPI_FUNC(char *) PyOS_double_to_string(double val,
- int mode,
 char format_code,
 int precision,
 int flags)
@@ -702,12 +706,15 @@
 	char* buf = (char *)PyMem_Malloc(512);
 	char lc_format_code = format_code;
 	char** float_strings = lc_float_strings;
+	Py_ssize_t n_wanted_digits_after_decimal = precision;
+	int mode = 0;
 
 	/* Validate format_code, and map upper and lower case */
 	switch (format_code) {
 	case 'e':
 	case 'f':
 	case 'g':
+	case 'r':
 		break;
 	case 'E':
 		lc_format_code = 'e';
@@ -726,11 +733,21 @@
 	if (format_code != lc_format_code)
 		float_strings = uc_float_strings;
 
-	/* don't touch precision if we're in mode 0, it should stay 0. if
-	 we're not using 'g', add one to the precision because we need to
-	 include the digit before the decimal. */
-	if (mode != 0 && lc_format_code != 'g')
+	switch (lc_format_code) {
+	case 'e':
+		mode = 2;
 		precision += 1;
+		break;
+	case 'f':
+		mode = 3;
+		break;
+	case 'g':
+		mode = 2;
+		break;
+	case 'r':
+		mode = 0;
+		break;
+	}
 
 //	printf("in PyOS_double_to_string %c %c\n", format_code, lc_format_code);
 	if (!buf)
@@ -738,7 +755,10 @@
 
 	/* XXX validate format_code */
 
-	format_float_short(buf, 512, val, lc_format_code, mode, precision, flags & Py_DTSF_SIGN, flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT, float_strings);
+	format_float_short(buf, 512, val, lc_format_code, mode, precision,
+			 n_wanted_digits_after_decimal, flags & Py_DTSF_SIGN,
+			 flags & Py_DTSF_ADD_DOT_0, flags & Py_DTSF_ALT,
+			 float_strings);
 
 	return buf;
 }


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /