Finished removing _PyOS_double_to_string, as mentioned in issue 7117.

This commit is contained in:
Eric Smith 2009-10-26 17:46:17 +00:00
parent 975d7576ca
commit c1bdf89145
5 changed files with 32 additions and 159 deletions

View File

@ -13,13 +13,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);
/* Use PyOS_double_to_string instead. It's the same, except it allocates
the appropriately sized buffer and returns it. This function will go
away in Python 2.8 and 3.2. */
PyAPI_FUNC(void) _PyOS_double_to_string(char *buf, size_t buf_len, double val,
char format_code, int precision,
int flags, int* type);
/* The caller is responsible for calling PyMem_Free to free the buffer
that's is returned. */
PyAPI_FUNC(char *) PyOS_double_to_string(double val,

View File

@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
Core and Builtins
-----------------
- Removed _PyOS_double_to_string. Use PyOS_double_to_string
instead. This is in preparation for (but not strictly related to)
issue #7117, short float repr.
- Issue #1087418: Boost performance of bitwise operations for longs.
- Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which

View File

@ -4336,7 +4336,10 @@ Py_LOCAL_INLINE(int)
formatfloat(char *buf, size_t buflen, int flags,
int prec, int type, PyObject *v)
{
char *tmp;
double x;
Py_ssize_t len;
x = PyFloat_AsDouble(v);
if (x == -1.0 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, "float argument required, "
@ -4381,9 +4384,20 @@ formatfloat(char *buf, size_t buflen, int flags,
"formatted float is too long (precision too large?)");
return -1;
}
_PyOS_double_to_string(buf, buflen, x, type, prec,
(flags&F_ALT)?Py_DTSF_ALT:0, NULL);
return (int)strlen(buf);
tmp = PyOS_double_to_string(x, type, prec,
(flags&F_ALT)?Py_DTSF_ALT:0, NULL);
if (!tmp)
return -1;
len = strlen(tmp);
if (len >= buflen) {
PyErr_SetString(PyExc_OverflowError,
"formatted float is too long (precision too large?)");
PyMem_Free(tmp);
return -1;
}
strcpy(buf, tmp);
PyMem_Free(tmp);
return (int)len;
}
/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and

View File

@ -8288,18 +8288,6 @@ strtounicode(Py_UNICODE *buffer, const char *charbuffer)
return len;
}
static int
doubletounicode(Py_UNICODE *buffer, size_t len, int format_code,
int precision, int flags, double x)
{
Py_ssize_t result;
_PyOS_double_to_string((char *)buffer, len, x, format_code, precision,
flags, NULL);
result = strtounicode(buffer, (char *)buffer);
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
}
static int
longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
{
@ -8323,6 +8311,8 @@ formatfloat(Py_UNICODE *buf,
PyObject *v)
{
double x;
Py_ssize_t result;
char *tmp;
x = PyFloat_AsDouble(v);
if (x == -1.0 && PyErr_Occurred())
@ -8365,8 +8355,15 @@ formatfloat(Py_UNICODE *buf,
"formatted float is too long (precision too large?)");
return -1;
}
return doubletounicode(buf, buflen, type, prec,
(flags&F_ALT)?Py_DTSF_ALT:0, x);
tmp = PyOS_double_to_string(x, type, prec,
(flags&F_ALT)?Py_DTSF_ALT:0, NULL);
if (!tmp)
return -1;
result = strtounicode(buf, tmp);
PyMem_Free(tmp);
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
}
static PyObject*

View File

@ -392,25 +392,6 @@ change_decimal_from_locale_to_dot(char* buffer)
}
Py_LOCAL_INLINE(void)
ensure_sign(char* buffer, size_t buf_size)
{
size_t len;
if (buffer[0] == '-')
/* Already have a sign. */
return;
/* Include the trailing 0 byte. */
len = strlen(buffer)+1;
if (len >= buf_size+1)
/* No room for the sign, don't do anything. */
return;
memmove(buffer+1, buffer, len);
buffer[0] = '+';
}
/* From the C99 standard, section 7.19.6:
The exponent always contains at least two digits, and only as many more digits
as necessary to represent the exponent.
@ -739,122 +720,6 @@ PyOS_ascii_formatd(char *buffer,
return _PyOS_ascii_formatd(buffer, buf_size, format, d, -1);
}
PyAPI_FUNC(void)
_PyOS_double_to_string(char *buf, size_t buf_len, double val,
char format_code, int precision,
int flags, int *ptype)
{
char format[32];
int t;
int upper = 0;
if (buf_len < 1) {
assert(0);
/* There's no way to signal this error. Just return. */
return;
}
buf[0] = 0;
/* Validate format_code, and map upper and lower case */
switch (format_code) {
case 'e': /* exponent */
case 'f': /* fixed */
case 'g': /* general */
break;
case 'E':
upper = 1;
format_code = 'e';
break;
case 'F':
upper = 1;
format_code = 'f';
break;
case 'G':
upper = 1;
format_code = 'g';
break;
case 'r': /* repr format */
/* Supplied precision is unused, must be 0. */
if (precision != 0)
return;
/* The repr() precision (17 significant decimal digits) is the
minimal number that is guaranteed to have enough precision
so that if the number is read back in the exact same binary
value is recreated. This is true for IEEE floating point
by design, and also happens to work for all other modern
hardware. */
precision = 17;
format_code = 'g';
break;
default:
assert(0);
return;
}
/* Check for buf too small to fit "-inf". Other buffer too small
conditions are dealt with when converting or formatting finite
numbers. */
if (buf_len < 5) {
assert(0);
return;
}
/* Handle nan and inf. */
if (Py_IS_NAN(val)) {
strcpy(buf, "nan");
t = Py_DTST_NAN;
} else if (Py_IS_INFINITY(val)) {
if (copysign(1., val) == 1.)
strcpy(buf, "inf");
else
strcpy(buf, "-inf");
t = Py_DTST_INFINITE;
} else {
t = Py_DTST_FINITE;
/* Build the format string. */
PyOS_snprintf(format, sizeof(format), "%%%s.%i%c",
(flags & Py_DTSF_ALT ? "#" : ""), precision,
format_code);
/* Have PyOS_snprintf do the hard work. */
PyOS_snprintf(buf, buf_len, format, val);
/* Do various fixups on the return string */
/* Get the current locale, and find the decimal point string.
Convert that string back to a dot. */
change_decimal_from_locale_to_dot(buf);
/* If an exponent exists, ensure that the exponent is at least
MIN_EXPONENT_DIGITS digits, providing the buffer is large
enough for the extra zeros. Also, if there are more than
MIN_EXPONENT_DIGITS, remove as many zeros as possible until
we get back to MIN_EXPONENT_DIGITS */
ensure_minimum_exponent_length(buf, buf_len);
/* Possibly make sure we have at least one character after the
decimal point (and make sure we have a decimal point). */
if (flags & Py_DTSF_ADD_DOT_0)
buf = ensure_decimal_point(buf, buf_len, precision);
}
/* Add the sign if asked and the result isn't negative. */
if (flags & Py_DTSF_SIGN && buf[0] != '-')
ensure_sign(buf, buf_len);
if (upper) {
/* Convert to upper case. */
char *p;
for (p = buf; *p; p++)
*p = Py_TOUPPER(*p);
}
if (ptype)
*ptype = t;
}
#ifdef PY_NO_SHORT_FLOAT_REPR
/* The fallback code to use if _Py_dg_dtoa is not available. */