[Python-checkins] r70754 - python/branches/py3k-short-float-repr/Objects/floatobject.c
mark.dickinson
python-checkins at python.org
Mon Mar 30 23:22:47 CEST 2009
Author: mark.dickinson
Date: Mon Mar 30 23:22:46 2009
New Revision: 70754
Log:
Hook up repr(float) to _Py_dg_dtoa.c
Modified:
python/branches/py3k-short-float-repr/Objects/floatobject.c
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 Mon Mar 30 23:22:46 2009
@@ -379,6 +379,94 @@
}
+/* convert a Python float to a minimal string that evaluates back to that
+ float. The output is minimal in the sense of having the least possible
+ number of significant digits. */
+
+static void
+format_float_short(char *buf, size_t buflen, PyFloatObject *v)
+{
+ double d;
+ char *digits, *digits_end;
+ int decpt, sign, exp_len;
+ size_t digits_len, i;
+
+ assert(PyFloat_Check(v));
+ d = PyFloat_AS_DOUBLE(v);
+
+ /* _Py_dg_dtoa returns a digit string (no decimal point
+ or exponent) */
+ digits = _Py_dg_dtoa(d, 0, 0, &decpt, &sign, &digits_end);
+ assert(digits_end != NULL && digits_end > digits);
+ digits_len = digits_end - digits;
+
+ if (!isdigit(digits[0])) {
+ /* infinities and nans here; adapt Gay's output,
+ so convert Infinity to inf and NaN to nan, and
+ ignore sign of nan. */
+ if (digits[0] == 'i' || digits[0] == 'I') {
+ if (sign == 1) {
+ *buf++ = '-';
+ }
+ strncpy(buf, "inf", 3);
+ buf += 3;
+ } else {
+ assert(digits[0] == 'n' || digits[0] == 'N');
+ strncpy(buf, "nan", 3);
+ buf += 3;
+ }
+ }
+ else if (-4 < decpt && decpt <= 17) {
+ if (sign == 1) {
+ *buf++ = '-';
+ }
+ /* use fixed-point notation if 1e-4 <= value < 1e17 */
+ if (decpt <= 0) {
+ /* output: 0.00...00dd...dd */
+ *buf++ = '0';
+ *buf++ = '.';
+ for (i=0; i < -decpt; i++)
+ *buf++ = '0';
+ strncpy(buf, digits, digits_len);
+ buf += digits_len;
+ }
+ else if (decpt < digits_len) {
+ /* output: dd...dd.dd...dd */
+ strncpy(buf, digits, decpt);
+ buf += decpt;
+ *buf++ = '.';
+ strncpy(buf, digits+decpt, digits_len-decpt);
+ buf += digits_len-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++)
+ *buf++ = '0';
+ *buf++ = '.';
+ *buf++ = '0';
+ }
+ }
+ else {
+ /* exponential notation: d[.dddd]e(+|-)ee;
+ at least 2 digits in exponent */
+ if (sign == 1) {
+ *buf++ = '-';
+ }
+ *buf++ = digits[0];
+ if (digits_len > 1) {
+ *buf++ = '.';
+ strncpy(buf, digits+1, digits_len-1);
+ buf += digits_len-1;
+ }
+ *buf++ = 'e';
+ exp_len = sprintf(buf, "%+.02d", decpt-1);
+ buf += exp_len;
+ }
+ *buf++ = '\0';
+}
+
static void
format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
{
@@ -439,7 +527,7 @@
float_repr(PyFloatObject *v)
{
char buf[100];
- format_float(buf, sizeof(buf), v, PREC_REPR);
+ format_float_short(buf, sizeof(buf), v);
return PyUnicode_FromString(buf);
}
More information about the Python-checkins
mailing list