[Python-checkins] r71077 - python/branches/py3k-short-float-repr/Python/pystrtod.c
eric.smith
python-checkins at python.org
Fri Apr 3 03:00:31 CEST 2009
Author: eric.smith
Date: Fri Apr 3 03:00:30 2009
New Revision: 71077
Log:
Cleaned up 'g' formatting case, only 4 tests left that fail. I'm not sure of the right thing to do in the marshal test failure. I also need to look at the locale test failure, that's probably an actual bug. Will look at the others.
Also cleaned up many comments and style issues.
Modified:
python/branches/py3k-short-float-repr/Python/pystrtod.c
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 Fri Apr 3 03:00:30 2009
@@ -519,8 +519,8 @@
};
-/* 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
+/* Convert a Python float to a minimal string that evaluates back to that
+ float. The output is minimal in the sense of having the fewest possible
number of significant digits. */
static void
@@ -534,10 +534,9 @@
int decpt, sign, exp_len;
int use_exp = 0;
int is_integer; /* is the output produced so far just an integer? */
- int add_padding;
+ int add_trailing_zeros;
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) */
@@ -546,9 +545,9 @@
n_digits = digits_end - digits;
if (n_digits && !isdigit(digits[0])) {
- /* infinities and nans here; adapt Gay's output,
+ /* Infinities and nans here; adapt Gay's output,
so convert Infinity to inf and NaN to nan, and
- ignore sign of nan. */
+ ignore sign of nan. Then return. */
if (digits[0] == 'i' || digits[0] == 'I') {
if (sign == 1) {
*buf++ = '-';
@@ -567,14 +566,18 @@
/* shouldn't get here: Gay's code should always return
something starting with a digit, an 'I', or an
'N' */
- printf("Help! dtoa returned: %.*s\n",
- (int)n_digits, digits);
+ /*printf("Help! dtoa returned: %.*s\n",
+ (int)n_digits, digits);*/
+ strncpy(buf, 'ERR', 3);
+ buf += 3;
assert(0);
}
*buf = '\0';
return;
}
+ /* We got digits back, format them. */
+
/* this replaces the various tests in other places like:
if (type == 'f' && fabs(x) >= 1e50)
type = 'g';
@@ -583,31 +586,25 @@
/* if (decpt > 50 && format_code == 'f')
format_code = 'g'; */
- /* detect if we're using exponents or not */
+ /* Detect if we're using exponents or not */
switch (format_code) {
- case 'e':
- use_exp = 1;
- break;
- case 'f':
- use_exp = 0;
- break;
+ case 'e': use_exp = 1; break;
+ case 'f': use_exp = 0; break;
case 'g': {
- int min_decpt = -4;
-
- if ((mode != 0) && (decpt > precision || decpt < min_decpt))
+ if ((mode != 0) && (decpt > precision || decpt < -4))
use_exp = 1;
- else
+ else {
use_exp = 0;
+ n_wanted_digits_after_decimal = precision - decpt;
+ }
}
}
- /* we got digits back, format them */
-
- if (sign == 1) {
+ /* Always add a negative sign, and a plus sign if always_add_sign. */
+ if (sign == 1)
*buf++ = '-';
- } else if (always_add_sign) {
+ else if (always_add_sign)
*buf++ = '+';
- }
if (use_exp) {
/* Exponential notation: d[.dddd]e(+|-)ee; at least 2 digits
@@ -617,6 +614,9 @@
*buf++ = '.';
strncpy(buf, digits + 1, n_digits_after_decimal);
buf += n_digits_after_decimal;
+
+ /* Don't add the exponent yet. That's done later after a bit
+ more formatting. */
} else {
/* Use fixed-point notation */
@@ -624,11 +624,14 @@
n_digits_after_decimal = n_digits - decpt;
if (decpt <= 0) {
- /* output: 0.00-00dd-dd */
+ /* Output: 0.00-00dd-dd */
*buf++ = '0';
*buf++ = '.';
- for (i = 0; i < -decpt; i++)
- *buf++ = '0';
+ /* Add the appropriate number of zeros. */
+ memset(buf, '0', -decpt);
+ buf += -decpt;
+
+ /* Then the digits */
strncpy(buf, digits, n_digits);
buf += n_digits;
}
@@ -642,29 +645,32 @@
}
else {
/* decpt >= n_digits. Output: dd-dd00-00.0 */
- strncpy(buf, digits, n_digits);
+ strncpy(buf, digits, n_digits); /* digits */
buf += n_digits;
- for (i = 0; i < decpt - n_digits; i++)
- *buf++ = '0';
+
+ memset(buf, '0', decpt - n_digits); /* zeros */
+ buf += decpt - n_digits;
+
*buf++ = '.';
}
}
/* Add trailing non-significant zeros for non-mode 0 and non-code g,
unless doing alt formatting */
- add_padding = 0;
+ add_trailing_zeros = 0;
if (mode != 0) {
if (format_code == 'g') {
if (use_alt_formatting)
- add_padding = 1;
+ add_trailing_zeros = 1;
}
else
- add_padding = 1;
+ add_trailing_zeros = 1;
}
- if (add_padding)
- for (i = n_digits_after_decimal; i < n_wanted_digits_after_decimal; i++)
- *buf++ = '0';
+ if (add_trailing_zeros) {
+ memset(buf, '0', n_wanted_digits_after_decimal - n_digits_after_decimal);
+ buf += n_wanted_digits_after_decimal - n_digits_after_decimal;
+ }
/* If we're at a trailing decimal, delete it. We are then just an integer. */
if (buf[-1] == '.') {
@@ -672,6 +678,8 @@
is_integer = 1;
}
else
+ /* The decimal isn't at the end, so it's somewhere else in the
+ string. We are therefore not an integer. */
is_integer = 0;
/* Now that we've done zero padding, add an exponent if needed. */
@@ -727,6 +735,8 @@
if (format_code != lc_format_code)
float_strings = uc_float_strings;
+ /* From the format code, compute the mode and make any adjustments as
+ needed. */
switch (lc_format_code) {
case 'e':
mode = 2;
@@ -746,7 +756,6 @@
break;
}
-// printf("in PyOS_double_to_string %c %c\n", format_code, lc_format_code);
if (!buf)
return NULL;
More information about the Python-checkins
mailing list