Finished removing _PyOS_double_to_string, as mentioned in issue 7117.
This commit is contained in:
parent
975d7576ca
commit
c1bdf89145
|
@ -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,
|
PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len,
|
||||||
const char *format, double d);
|
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
|
/* The caller is responsible for calling PyMem_Free to free the buffer
|
||||||
that's is returned. */
|
that's is returned. */
|
||||||
PyAPI_FUNC(char *) PyOS_double_to_string(double val,
|
PyAPI_FUNC(char *) PyOS_double_to_string(double val,
|
||||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 2.7 alpha 1
|
||||||
Core and Builtins
|
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 #1087418: Boost performance of bitwise operations for longs.
|
||||||
|
|
||||||
- Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which
|
- Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which
|
||||||
|
|
|
@ -4336,7 +4336,10 @@ Py_LOCAL_INLINE(int)
|
||||||
formatfloat(char *buf, size_t buflen, int flags,
|
formatfloat(char *buf, size_t buflen, int flags,
|
||||||
int prec, int type, PyObject *v)
|
int prec, int type, PyObject *v)
|
||||||
{
|
{
|
||||||
|
char *tmp;
|
||||||
double x;
|
double x;
|
||||||
|
Py_ssize_t len;
|
||||||
|
|
||||||
x = PyFloat_AsDouble(v);
|
x = PyFloat_AsDouble(v);
|
||||||
if (x == -1.0 && PyErr_Occurred()) {
|
if (x == -1.0 && PyErr_Occurred()) {
|
||||||
PyErr_Format(PyExc_TypeError, "float argument required, "
|
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?)");
|
"formatted float is too long (precision too large?)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_PyOS_double_to_string(buf, buflen, x, type, prec,
|
tmp = PyOS_double_to_string(x, type, prec,
|
||||||
(flags&F_ALT)?Py_DTSF_ALT:0, NULL);
|
(flags&F_ALT)?Py_DTSF_ALT:0, NULL);
|
||||||
return (int)strlen(buf);
|
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
|
/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and
|
||||||
|
|
|
@ -8288,18 +8288,6 @@ strtounicode(Py_UNICODE *buffer, const char *charbuffer)
|
||||||
return len;
|
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
|
static int
|
||||||
longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
|
longtounicode(Py_UNICODE *buffer, size_t len, const char *format, long x)
|
||||||
{
|
{
|
||||||
|
@ -8323,6 +8311,8 @@ formatfloat(Py_UNICODE *buf,
|
||||||
PyObject *v)
|
PyObject *v)
|
||||||
{
|
{
|
||||||
double x;
|
double x;
|
||||||
|
Py_ssize_t result;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
x = PyFloat_AsDouble(v);
|
x = PyFloat_AsDouble(v);
|
||||||
if (x == -1.0 && PyErr_Occurred())
|
if (x == -1.0 && PyErr_Occurred())
|
||||||
|
@ -8365,8 +8355,15 @@ formatfloat(Py_UNICODE *buf,
|
||||||
"formatted float is too long (precision too large?)");
|
"formatted float is too long (precision too large?)");
|
||||||
return -1;
|
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*
|
static PyObject*
|
||||||
|
|
|
@ -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:
|
/* From the C99 standard, section 7.19.6:
|
||||||
The exponent always contains at least two digits, and only as many more digits
|
The exponent always contains at least two digits, and only as many more digits
|
||||||
as necessary to represent the exponent.
|
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);
|
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
|
#ifdef PY_NO_SHORT_FLOAT_REPR
|
||||||
|
|
||||||
/* The fallback code to use if _Py_dg_dtoa is not available. */
|
/* The fallback code to use if _Py_dg_dtoa is not available. */
|
||||||
|
|
Loading…
Reference in New Issue