[Python-checkins] r71135 - python/branches/py3k-short-float-repr/Python/pystrtod.c
mark.dickinson
python-checkins at python.org
Sat Apr 4 11:40:47 CEST 2009
Author: mark.dickinson
Date: Sat Apr 4 11:40:47 2009
New Revision: 71135
Log:
Reworking of float_format_short. Eric, feel free to revert this if you
don't like it, or for any other reason...
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 Sat Apr 4 11:40:47 2009
@@ -531,12 +531,10 @@
int use_alt_formatting, char **float_strings)
{
char *digits, *digits_end;
- int decpt, sign, exp_len;
+ int decpt, sign, exp_len, dec_pos;
int use_exp = 0;
int is_integer; /* is the output produced so far just an integer? */
- int add_trailing_zeros;
- Py_ssize_t n_digits_after_decimal = 0;
- Py_ssize_t n_digits;
+ Py_ssize_t n_digits, trailing_zeros;
/* precision of 0 makes no sense for 'g' format; interpret as 1 */
if (precision == 0 && format_code == 'g')
@@ -592,15 +590,25 @@
/* 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;
+ trailing_zeros = precision - n_digits;
+ break;
+ case 'f':
+ use_exp = 0;
+ trailing_zeros = decpt + precision - n_digits;
+ break;
case 'g':
if ((mode != 0) && (decpt > precision || decpt <= -4))
use_exp = 1;
else {
use_exp = 0;
- n_wanted_digits_after_decimal = precision - decpt;
}
+ if (use_alt_formatting)
+ trailing_zeros = precision - n_digits;
+ else
+ trailing_zeros = 0;
+ break;
}
/* Always add a negative sign, and a plus sign if always_add_sign. */
@@ -609,74 +617,47 @@
else if (always_add_sign)
*buf++ = '+';
- if (use_exp) {
- /* Exponential notation: d[.dddd]e(+|-)ee; at least 2 digits
- in exponent */
- n_digits_after_decimal = n_digits - 1;
- *buf++ = digits[0];
- *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 */
-
- /* Be aware that n_digits_after_decimal can be negative! */
- n_digits_after_decimal = n_digits - decpt;
-
- if (decpt <= 0) {
- /* Output: 0.00-00dd-dd */
- *buf++ = '0';
- *buf++ = '.';
- /* Add the appropriate number of zeros. */
- memset(buf, '0', -decpt);
- buf += -decpt;
-
- /* Then the digits */
- strncpy(buf, digits, n_digits);
- buf += n_digits;
- }
- else if (decpt < n_digits) {
- /* Output: dd-dd.dd-dd */
- strncpy(buf, digits, decpt);
- buf += decpt;
- *buf++ = '.';
- strncpy(buf, digits + decpt, n_digits - decpt);
- buf += n_digits - decpt;
- }
- else {
- /* decpt >= n_digits. Output: dd-dd00-00.0 */
- strncpy(buf, digits, n_digits); /* digits */
- buf += n_digits;
-
- memset(buf, '0', decpt - n_digits); /* zeros */
- buf += decpt - n_digits;
+ /* dec_pos = position of decimal point in buffer */
+ if (use_exp)
+ dec_pos = 1;
+ else
+ dec_pos = decpt;
- *buf++ = '.';
- }
+ /* zero padding on left of digit string */
+ if (dec_pos <= 0) {
+ *buf++ = '0';
+ *buf++ = '.';
+ memset(buf, '0', -dec_pos);
+ buf -= dec_pos;
}
- /* Add trailing non-significant zeros for non-mode 0 and non-code g,
- unless doing alt formatting */
- add_trailing_zeros = 0;
- if (mode != 0) {
- if (format_code == 'g') {
- if (use_alt_formatting)
- add_trailing_zeros = 1;
- }
- else
- add_trailing_zeros = 1;
+ /* digits, with included decimal point */
+ if (0 < dec_pos && dec_pos <= n_digits) {
+ strncpy(buf, digits, dec_pos);
+ buf += dec_pos;
+ *buf++ = '.';
+ strncpy(buf, digits+dec_pos, n_digits-dec_pos);
+ buf += n_digits-dec_pos;
}
-
- 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;
+ else {
+ strncpy(buf, digits, n_digits);
+ buf += n_digits;
+ }
+ /* and zeros on the right up to the decimal point */
+ if (n_digits < dec_pos) {
+ memset(buf, '0', dec_pos-n_digits);
+ buf += dec_pos-n_digits;
+ *buf++ = '.';
+ trailing_zeros -= dec_pos-n_digits;
+ }
+ /* and more trailing zeros, when necessary */
+ if (trailing_zeros > 0) {
+ memset(buf, '0', trailing_zeros);
+ buf += trailing_zeros;
}
/* If we're at a trailing decimal, delete it. We are then just an integer. */
- if (buf[-1] == '.') {
+ if (buf[-1] == '.' && !(format_code == 'g' && use_alt_formatting)) {
buf--;
is_integer = 1;
}
More information about the Python-checkins
mailing list