[Python-checkins] r70785 - in python/branches/py3k-short-float-repr: Objects/complexobject.c Python/pystrtod.c
eric.smith
python-checkins at python.org
Tue Mar 31 02:01:17 CEST 2009
Author: eric.smith
Date: Tue Mar 31 02:01:17 2009
New Revision: 70785
Log:
Checkpoint. Memory management still needs work.
Modified:
python/branches/py3k-short-float-repr/Objects/complexobject.c
python/branches/py3k-short-float-repr/Python/pystrtod.c
Modified: python/branches/py3k-short-float-repr/Objects/complexobject.c
==============================================================================
--- python/branches/py3k-short-float-repr/Objects/complexobject.c (original)
+++ python/branches/py3k-short-float-repr/Objects/complexobject.c Tue Mar 31 02:01:17 2009
@@ -345,62 +345,107 @@
}
-static void
-complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision)
+static int
+complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int mode,
+ int precision)
{
- char format[32];
- if (v->cval.real == 0.) {
- if (!Py_IS_FINITE(v->cval.imag)) {
- if (Py_IS_NAN(v->cval.imag))
- strncpy(buf, "nan*j", 6);
- else if (copysign(1, v->cval.imag) == 1)
- strncpy(buf, "inf*j", 6);
- else
- strncpy(buf, "-inf*j", 7);
- }
- else {
- PyOS_snprintf(format, sizeof(format), "%%.%ig", precision);
- PyOS_ascii_formatd(buf, bufsz - 1, format, v->cval.imag);
- strncat(buf, "j", 1);
- }
- } else {
- char re[64], im[64];
- /* Format imaginary part with sign, real part without */
- if (!Py_IS_FINITE(v->cval.real)) {
- if (Py_IS_NAN(v->cval.real))
- strncpy(re, "nan", 4);
- /* else if (copysign(1, v->cval.real) == 1) */
- else if (v->cval.real > 0)
- strncpy(re, "inf", 4);
- else
- strncpy(re, "-inf", 5);
- }
- else {
- PyOS_snprintf(format, sizeof(format), "%%.%ig", precision);
- PyOS_ascii_formatd(re, sizeof(re), format, v->cval.real);
- }
- if (!Py_IS_FINITE(v->cval.imag)) {
- if (Py_IS_NAN(v->cval.imag))
- strncpy(im, "+nan*", 6);
- /* else if (copysign(1, v->cval.imag) == 1) */
- else if (v->cval.imag > 0)
- strncpy(im, "+inf*", 6);
- else
- strncpy(im, "-inf*", 6);
- }
- else {
- PyOS_snprintf(format, sizeof(format), "%%+.%ig", precision);
- PyOS_ascii_formatd(im, sizeof(im), format, v->cval.imag);
- }
- PyOS_snprintf(buf, bufsz, "(%s%sj)", re, im);
- }
+ int result = -1;
+ char* p;
+
+ /* If these are non-NULL, they'll need to be freed. */
+ char* pre = NULL;
+ char* pim = NULL;
+
+ /* These do not need to be freed. They're either aliases for pim
+ and pre, or pointers to constants. */
+ char* re = NULL;
+ char* im = NULL;
+ char* lead = "";
+ char* tail = "";
+
+ Py_ssize_t len;
+
+ if (v->cval.real == 0.) {
+ re = "";
+ if (!Py_IS_FINITE(v->cval.imag)) {
+ if (Py_IS_NAN(v->cval.imag))
+ im = "nan*";
+ else if (copysign(1, v->cval.imag) == 1)
+ im = "inf*";
+ else
+ im = "-inf*";
+ }
+ else {
+ pim = PyOS_double_to_string(v->cval.imag, mode, 'g', precision, 0, 0);
+ if (!pim) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ im = pim;
+ }
+ } else {
+ /* Format imaginary part with sign, real part without */
+ if (!Py_IS_FINITE(v->cval.real)) {
+ if (Py_IS_NAN(v->cval.real))
+ re = "nan";
+ /* else if (copysign(1, v->cval.real) == 1) */
+ else if (v->cval.real > 0)
+ re = "inf";
+ else
+ re = "-inf";
+ }
+ else {
+ pre = PyOS_double_to_string(v->cval.real, mode, 'g', precision, 0, 0);
+ if (!pre) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ re = pre;
+ }
+
+ if (!Py_IS_FINITE(v->cval.imag)) {
+ if (Py_IS_NAN(v->cval.imag))
+ im = "+nan*";
+ /* else if (copysign(1, v->cval.imag) == 1) */
+ else if (v->cval.imag > 0)
+ im = "+inf*";
+ else
+ im = "-inf*";
+ }
+ else {
+ pim = PyOS_double_to_string(v->cval.imag, mode, 'g', precision, 1, 0);
+ if (!pim) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ im = pim;
+ }
+ lead = "(";
+ tail = ")";
+ }
+ /* Alloc the final buffer. Add one for the "j" in the format string. */
+ len = strlen(lead) + strlen(re) + strlen(im) + strlen(tail) + 2;
+ p = PyMem_Malloc(len);
+ if (!p) {
+ PyErr_NoMemory();
+ goto done;
+ }
+ PyOS_snprintf(p, len, "%s%s%sj%s", lead, re, im, tail);
+ strcpy(buf, p);
+ result = 0;
+done:
+ PyMem_Free(pim);
+ PyMem_Free(pre);
+
+ return result;
}
static PyObject *
complex_repr(PyComplexObject *v)
{
char buf[100];
- complex_to_buf(buf, sizeof(buf), v, PREC_REPR);
+ if (complex_to_buf(buf, sizeof(buf), v, 0, 0) < 0)
+ return PyErr_NoMemory();
return PyUnicode_FromString(buf);
}
@@ -408,7 +453,8 @@
complex_str(PyComplexObject *v)
{
char buf[100];
- complex_to_buf(buf, sizeof(buf), v, PREC_STR);
+ if (complex_to_buf(buf, sizeof(buf), v, 2, PREC_STR) < 0)
+ return PyErr_NoMemory();
return PyUnicode_FromString(buf);
}
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 Tue Mar 31 02:01:17 2009
@@ -495,7 +495,7 @@
number of significant digits. */
static void
-format_float_short(char *buf, size_t buflen, double d, int mode, int precision)
+format_float_short(char *buf, size_t buflen, double d, int mode, int precision, int always_add_sign, int add_dot_0_if_integer)
{
char *digits, *digits_end;
int decpt, sign, exp_len;
@@ -515,6 +515,9 @@
if (sign == 1) {
*buf++ = '-';
}
+ else if (always_add_sign) {
+ *buf++ = '+';
+ }
strncpy(buf, "inf", 3);
buf += 3;
} else {
@@ -526,6 +529,8 @@
else if (-4 < decpt && decpt <= 17) {
if (sign == 1) {
*buf++ = '-';
+ } else if (always_add_sign) {
+ *buf++ = '+';
}
/* use fixed-point notation if 1e-4 <= value < 1e17 */
if (decpt <= 0) {
@@ -551,8 +556,10 @@
buf += digits_len;
for (i=0; i < decpt-digits_len; i++)
*buf++ = '0';
- *buf++ = '.';
- *buf++ = '0';
+ if (add_dot_0_if_integer) {
+ *buf++ = '.';
+ *buf++ = '0';
+ }
}
}
else {
@@ -560,6 +567,8 @@
at least 2 digits in exponent */
if (sign == 1) {
*buf++ = '-';
+ } else if (always_add_sign) {
+ *buf++ = '+';
}
*buf++ = digits[0];
if (digits_len > 1) {
@@ -578,7 +587,7 @@
int mode,
char format_code,
int precision,
- int sign,
+ int always_add_sign,
int add_dot_0_if_integer)
{
char fmt[32];
@@ -590,26 +599,7 @@
/* XXX validate format_code */
- format_float_short(buf, 512, val, mode, precision);
-
- if (add_dot_0_if_integer) {
- /* If the result was just an integer, without a decimal, then
- add ".0" to the end of the string. */
- char *cp = buf;
- if (*cp == '-')
- cp++;
- for (; *cp != '\0'; cp++) {
- /* Any non-digit means it's not an integer;
- this takes care of NAN and INF as well. */
- if (!isdigit(Py_CHARMASK(*cp)))
- break;
- }
- if (*cp == '\0') {
- *cp++ = '.';
- *cp++ = '0';
- *cp++ = '\0';
- }
- }
+ format_float_short(buf, 512, val, mode, precision, always_add_sign, add_dot_0_if_integer);
return buf;
}
More information about the Python-checkins
mailing list