[Python-checkins] r46169 - sandbox/trunk/decimal-c/_decimal.c

jack.diederich python-checkins at python.org
Wed May 24 15:14:24 CEST 2006


Author: jack.diederich
Date: Wed May 24 15:14:23 2006
New Revision: 46169

Modified:
   sandbox/trunk/decimal-c/_decimal.c
Log:
* str() formatting for non-eng/sci

Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Wed May 24 15:14:23 2006
@@ -2058,24 +2058,134 @@
     return NULL;
 }
 
+/*
+  max length of output is len(str(max_long)) + len(str(max_long)) + 
+  len(".") + len("-")
+*/
+#define FORMAT_SIZE 50
+#define SANITY_CHECK(x) assert((x) < end);
+
+static PyObject *
+decimal_special_str(decimalobject *d)
+{
+    char outbuf[FORMAT_SIZE];
+    char *p, *end;
+    int i;
+    end = &outbuf[FORMAT_SIZE];
+    p = outbuf;
+
+    if (d->sign & 1)
+        *p++ = '-';
+
+    if (GETNAN(d)) {
+        if (GETNAN(d) == 2)
+            *p++ = 's';
+        SANITY_CHECK(p);
+        p += sprintf(p, "%s", "NaN");
+        SANITY_CHECK(p);
+
+        /* check for digits != {0, } */
+        if (d->ob_size != 1 || d->digits[0] != 0) {
+            for (i = 0; i < d->ob_size; i++) {
+                p += sprintf(p, "%d", d->digits[i]);
+                SANITY_CHECK(p);
+            }
+        }
+    } else { /* infinity */
+        p += sprintf(p, "%s", "Infinity");
+    }
+    *p++ = 0;
+    SANITY_CHECK(p);
+    return PyString_FromString(p);
+}
+
 static PyObject *
 decimal_str(decimalobject *d)
 {
-    char buf[1000];
-    char dig[2];
-    long i;
+    char outbuf[FORMAT_SIZE];
+    int i, imax, j;
+    int leftdigits, dotplace, adjexp;
+    int append_E = 0, append_adjexp = 0;
+    char *p, *end;
+    end = &outbuf[FORMAT_SIZE];
+    contextobject *context = NULL; /* debug, make this an arg */
+
+    if (ISSPECIAL(d))
+        return decimal_special_str(d);
+
+    if (context == NULL) {
+        context = getcontext();
+        if (!context)
+            return NULL;
+    }
+    if (d->sign & 1) {
+        outbuf[0] = '-';
+        p = &outbuf[1];
+    } else {
+        p = &outbuf[0];
+    }
+    
+    leftdigits = d->exp + d->ob_size;
+    adjexp = leftdigits - 1;
+    dotplace = 1;
+    if (d->exp) {
+        dotplace = -1; /* no dot */
+    } else if (d->exp < 0 && adjexp >= 0) {
+        dotplace = leftdigits;
+    } else if (d->exp < 0 && adjexp >= -6) {
+        for (i = leftdigits; i < 0; i++) {
+            *p++ = '0';
+            SANITY_CHECK(p);
+        }
+        *p++ = '0';
+    } else {
+        if (d->ob_size <= dotplace)
+            dotplace = -1;
 
-    /*if (ISSPECIAL(d)) {
-        if (ISNAN(d))
-    */
-    dig[1] = 0;
-    PyOS_snprintf(buf, 1000, "sign=%i, exp=%ld, digits=", d->sign, d->exp);
-    for (i = 0; i < d->ob_size; i++) {
-        dig[0] = d->digits[i]+48;
-        strcat(buf, dig);
+        if (adjexp) {
+            append_E = 1;
+            append_adjexp = 1;
+        }
+    }
+    
+    imax = d->ob_size;
+    if (dotplace > 0) {
+        imax++;
+    }
+    for (i = 0, j = 0; i < imax; i++) {
+        if (i == dotplace) {
+            *p++ = '.';
+            SANITY_CHECK(p);
+            continue;
+        } else {
+            p += sprintf(p, "%d", d->digits[j]);
+            SANITY_CHECK(p);
+            j++;
+        }
+    }
+
+    if (append_E) {
+        if (context->capitals) {
+            *p++ = 'E';
+            SANITY_CHECK(p);
+            if (adjexp > 0) {
+                *p++ = '+';
+                SANITY_CHECK(p);
+            }
+        } else {
+            *p++ = 'e';
+            SANITY_CHECK(p);
+        }
+    }
+    if (append_adjexp) {
+        p += sprintf(p, "%d", adjexp);
     }
-    return PyString_FromString(buf);
+    SANITY_CHECK(p);
+    *p++ = 0;
+    SANITY_CHECK(p);
+    return PyString_FromString(&outbuf);
 }
+#undef SANITY_CHECK
 
 static PyObject *
 decimal_repr(decimalobject *d)


More information about the Python-checkins mailing list