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

mateusz.rukowicz python-checkins at python.org
Mon Jun 12 22:39:26 CEST 2006


Author: mateusz.rukowicz
Date: Mon Jun 12 22:39:25 2006
New Revision: 46897

Modified:
   sandbox/trunk/decimal-c/_decimal.c
Log:
Now code is C89 compatible, added little explanation of what 'limb' is. Indentation fixes cooming soon.


Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Mon Jun 12 22:39:25 2006
@@ -70,6 +70,14 @@
 #include <stdio.h>
 
 /* integer arithmetic */
+/* Little explanation:
+ * Digits are grouped into limbs, that is, every limb keeps LOG digits.
+ * Arithmetic perfomred on those limbs are very the same that in base 10
+ * but insetad of dealing "digits" 0-9, we deal with "digits" 0-(BASE -1)
+ * Note, that first limb is least significant.
+ * Further in code when I say "limbs" I mean one calculation unit, and 
+ * when I say "digit" I mean digit between 0-9 (limb consists of LOG digits).
+ */
 
 /* takes new_digits from self[], starting from start_at digit, *digits* not limbs */
 /* returns digit after that we returned (useful for rounding) */
@@ -154,6 +162,7 @@
 		return last_digit;
 }
 
+/* cuts least significant digit */
 static void
 _limb_cut_one_digit(long *self, long ndigits)
 {
@@ -374,7 +383,6 @@
 #define GETNAN(op)    ( ( (op)->sign == SIGN_POSNAN  || (op)->sign == SIGN_NEGNAN ) ? \
                         1 : ( ( (op)->sign == SIGN_POSSNAN || (op)->sign == SIGN_NEGSNAN ) ? 2 : 0 ) )
 
-//#define ISINF(op)     ((op)->sign == SIGN_POSINF  || (op)->sign == SIGN_NEGINF)
 #define ISINF(op)	( ( (op)->sign == SIGN_POSINF || (op)->sign == SIGN_NEGINF) ?  \
 						((op)->sign == SIGN_POSINF ? 1 : -1) : 0 )
 		
@@ -561,7 +569,6 @@
     }
     assert(PyDecimal_Check(thing));
     /* we want to return a NaN, but keep diagnostics */
-//    sign = ((thing->sign&1 == 0) ? SIGN_POSNAN : SIGN_NEGNAN);
 	if(thing->sign&1)		/* neg */
 		sign = SIGN_NEGNAN;
 	else
@@ -831,35 +838,10 @@
 
     if (!new) return NULL;
     
-    /* determine if we need a new digit */
-//    for (spot = 0; spot < self->ob_size; spot++) {
-//        if (self->digits[spot] != 9) {
-//            spot = -1;
-//            break;
-//        }
-//    }
-//    if (spot == -1) {
-        /* no new digit needed */
-//        new->ob_size--;
-//        for (spot = 0; spot < self->ob_size; spot++)
-//            new->digits[spot] = self->digits[spot];
-//    } else {
-//        for (spot = 0; spot < self->ob_size; spot++)
-//            new->digits[spot+1] = self->digits[spot];
-//		new->digits[0] = 0;
-//    }
-
-//    spot = new->ob_size-1;
-//    new->digits[spot]++;
-//    while (new->digits[spot] == 10) {
-//        new->digits[spot] = 0;
-//        spot--;
- //       assert(spot >= 0);
-//        new->digits[spot]++;
-//    }
 
 	for(i=0;i<self->limb_count;i++)
 			new->limbs[i] = self->limbs[i];
+	
 	if(self->limb_count != new->limb_count)
 		new->limbs[new->limb_count - 1] = 0;	/* we have new limb */
 
@@ -894,7 +876,7 @@
 /* Round away from 0. */
 static decimalobject *
 _round_up(decimalobject *self, long prec, long expdiff, contextobject *ctx)			
-{			/* XXX temporary solution with limbs */
+{			
     long i;
     decimalobject *new = _NEW_decimalobj(prec, self->sign, self->exp + expdiff);
     decimalobject *new2 = NULL;
@@ -905,7 +887,6 @@
 	
     for (i = prec; i < self->ob_size; i++)
 		if(_limb_get_digit(self->limbs,self->ob_size, i) > 0){		/* SLOW */
-//        if (self->digits[i] > 0) {
             new2 = _decimal_increment(new, 1, ctx);
             Py_DECREF(new);
             if (!new2)
@@ -931,7 +912,6 @@
 {
     decimalobject *new;
     assert(expdiff > 0);
-//    if (self->ob_size > prec && self->digits[prec] >= 5) {
 	if(self->ob_size > prec && _limb_get_digit(self->limbs, self->ob_size, prec) >= 5){	/* SLOW */
 		new = _decimal_increment(tmp, 1, ctx);
         Py_DECREF(tmp);
@@ -960,11 +940,9 @@
         tmp->digits[i] = self->digits[i];
 
 	last = _limb_first_n_digits(self->limbs, self->ob_size, 0, tmp->limbs, prec);
-//	assert(self->digits[prec] == last);
     if (last == 5) {
         for (i = prec+1; i < self->ob_size; i++) {
 			if(_limb_get_digit(self->limbs, self->ob_size, i) != 0)	/* SLOW */
-    //        if (self->digits[i] != 0)
                 return _do_round_half_up(self, prec, expdiff, ctx, tmp);
         }
         /* self ends in 5000...., so tmp is okay */
@@ -988,10 +966,8 @@
     if (last == 5) {
         for (i = prec+1; i < self->ob_size; i++) {
 			if(_limb_get_digit(self->limbs, self->ob_size, i) != 0)	/* SLOW */
-//            if (self->digits[i] != 0)
                 return _do_round_half_up(self, prec, expdiff, ctx, tmp);
         }
-//        if ((self->digits[prec-1] & 1) == 0)
 		if((_limb_get_digit(self->limbs, self->ob_size, prec-1)&1) == 0)
 			return tmp;
     }
@@ -1133,12 +1109,11 @@
 
     /* Maybe all the lost digits are 0. */
     for (i = self->ob_size - expdiff; i < self->ob_size; i++) {
-//        if (self->digits[i] > 0)
 		if(_limb_get_digit(self->limbs, self->ob_size, i) > 0)
 			goto no_way;
     }
     /* All lost digits are 0, so just clobber new */
-//    new->ob_size = prec;
+
 	while(new->ob_size > prec)
 	{
 		_limb_cut_one_digit(new->limbs, new->ob_size);	/* VERY SLOW */
@@ -1154,15 +1129,16 @@
 no_way:
     /* Now rounding starts. We still own "new". */
     rnd_func = round_funcs[rounding];
-//    if (prec != ctx->prec) {
-//        ctx2 = (contextobject *)context_copy(ctx);
-//        if (!ctx2) {
-//            Py_DECREF(new);
-//            return NULL;
-//        }
-//        ctx2->prec = prec;
-//        ctx = ctx2;
-  /*  }*/	/* XXX here is quite subtle bug - we copy context, and set flags in copied context
+	/*
+    if (prec != ctx->prec) {
+        ctx2 = (contextobject *)context_copy(ctx);
+        if (!ctx2) {
+            Py_DECREF(new);
+            return NULL;
+        }
+        ctx2->prec = prec;
+        ctx = ctx2;
+    }*/	/* XXX here is quite subtle bug - we copy context, and set flags in copied context
 		   after that, they are lost, not sure if we really need function above,
 		   I'll comment it */
 	
@@ -1251,12 +1227,10 @@
     if (!tmp)
         return NULL;
 
-//    if (tmp->digits[0] == 0 && tmp->ob_size > 1) {
 	if(_limb_get_digit(tmp -> limbs, tmp->ob_size, 0) == 0 && tmp->ob_size > 1){
 	/* We need one digit less, just clobber tmp. */
         for (i = 0; i < tmp->ob_size-1; i++)
-            tmp->digits[i] = tmp->digits[i+1];
-//		_limb_cut_one_digit(tmp->limbs, tmp->ob_size);
+            tmp->digits[i] = tmp->digits[i+1];	/* TODO make last digit 0 */
 		tmp->ob_size--;
     }
     tmp->exp = exp;
@@ -1579,10 +1553,8 @@
              
   next:
     /* Adjusted sizes are not equal. */
-//    if (adj1 > adj2 && self->digits[0] != 0)
 	if(adj1 > adj2 && _limb_get_digit(self->limbs, self->ob_size, 0) != 0)
 		return 1 - 2*(self->sign & 1); /* 0 -> 1, 1 -> -1 */
-//    else if (adj1 < adj2 && other->digits[0] != 0)
 	else if(adj1 < adj2 && _limb_get_digit(other->limbs, other->ob_size, 0) != 0)
 		return -1 + 2*(other->sign & 1);
 
@@ -1595,7 +1567,6 @@
 
 	Py_XDECREF(ctx2);
 
-    /* XXX: WTF? */
     ans = _do_decimal_subtract(self, other, ctx2);
     if (!ans) return 0;
 
@@ -1820,7 +1791,6 @@
     }
     
     /* strip trailing 0s from dup */
-//    while (dup->digits[dup->ob_size - 1] == 0) {
 	while(_limb_get_digit(dup->limbs, dup->ob_size, dup->ob_size -1) == 0){
 		_limb_cut_one_digit(dup->limbs,dup->ob_size);
 		dup->ob_size --;
@@ -2116,11 +2086,6 @@
         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);
-//            }
 		if(d->ob_size != 1 || _limb_get_digit(d->limbs, d->ob_size, 0) != 0)
 		{
 			for(i=0;i< d->ob_size;i++)
@@ -2152,20 +2117,14 @@
         SANITY_CHECK(p);
     }
     if (d->exp < 0 && d->exp >= -6) {
-        /* figure out the right number of digits */
-//        i = sprintf(p, "0.%0*d", abs(d->exp), 0);
-        /* and write those as zeros */
-//        for (; i > 0; i--) {
-//            *p++ = '0';
-//        }
+		
 		i = 0;
 		*p++ = '0';
 		*p++ = '.';
-		for(;i<abs(d->exp);i++)
+		for (;i<abs(d->exp);i++)
 			*p++ = '0';
         SANITY_CHECK(p);
     } else {
-//        roundexp = ((d->exp - 1)/3 + 1) * 3; /* nearest gt mult of 3 */
 		roundexp = d->exp;
 		while(roundexp%3)
 			roundexp ++;
@@ -2274,7 +2233,6 @@
 		{
 			adjexp --;
 			dotplace ++;
-//			extra_zeros ++;
 		}
 
 	/* now all we have to do, is to put it to the string =] */
@@ -2302,61 +2260,6 @@
 	
 	/* that was a way easier way =] */
 	
-//    if (engineering) {
-//        dotplace = (leftdigits-1)%3+1;
-//        adjexp = leftdigits -1 - (leftdigits-1)%3;
-//    } else {
-//        dotplace = 1;
-//        adjexp = leftdigits - 1;
-//    }
-//    if (d->exp == 0) {
-//        dotplace = -1; /* no dot */
-//    } else if (d->exp < 0 && adjexp >= 0) {
-//       dotplace = leftdigits;
-//    } else if (d->exp < 0 && adjexp >= -6) {
-//        if (!engineering) { /* eng has no leading zeros */
-//            for (i = leftdigits; i < 0; i++) {
-//                *p++ = '0';
-//                SANITY_CHECK(p);
-//            }
-//            *p++ = '0';
-//        }
-//    } else {
-//        if (d->ob_size <= dotplace)
-//            dotplace = -1;
-
-//        if (adjexp) {
-//            append_E = 1;
-//            append_adjexp = 1;
-//        }
-//    }
-    
-//    imax = d->ob_size;
-//    if (dotplace > 0) {
-//        imax++;
-//    }
-//    if (engineering) { /* eng has no leading zeros */
-//        for (i = 0, j = 0; i < imax; i++) {
-//            if (d->digits[j] == 0) {
-//			if(_limb_get_digit(d->limbs, d->ob_size, j) == 0){
-//				j++;
-//            } else {
-//                break;
-//            }
-//        }
-//    }
-//    for (i = 0, j = 0; i < imax; i++) {
-//        if (i == dotplace) {
-//            *p++ = '.';
-//            SANITY_CHECK(p);
-//            continue;
-//        } else {
-//            p += sprintf(p, "%d", d->digits[j]);
-//			p += sprintf(p, "%d", _limb_get_digit(d->limbs, d->ob_size, j));	/* SLOW */
-//			SANITY_CHECK(p);
-//            j++;
-//        }
-//    }
 
 	if(adjexp)
 	{
@@ -2384,14 +2287,6 @@
     *p++ = 0;
     SANITY_CHECK(p);
     
-    /* if engineering and (just a sign | empty | starts with a dot or an E) */
-//    if (engineering && ((p - &outbuf[1] > (d->sign & 1)) || outbuf[1] == '.' ||
-//                        outbuf[1] == 'E' || outbuf[1] == 'e')) {
-//        outbuf[0] = '0';
-//        p = outbuf;
-//    } else {
-//        p = &outbuf[1];
-//    }
 	p = &outbuf[1];
     SANITY_CHECK(p);
     ret = PyString_FromString(p);
@@ -2748,19 +2643,20 @@
 		max_size = _limb_add(o1->limbs, o1->ob_size, o2->limbs, o2->ob_size, ret->limbs);
 		ret->ob_size = max_size;
 		ret->limb_count = (max_size + LOG -1)/LOG;
-//		Py_DECREF(o1);
-//		Py_DECREF(o2);
-//		if(shouldround)
-//		{
-//			fixed = _decimal_fix(ret, ctx);
-//			Py_DECREF(ret);
-//			if(!fixed)
-//			{
-//				return NULL;
-//			}
-//			return fixed;
-//		}
-//		return ret;
+/*
+		Py_DECREF(o1);
+		Py_DECREF(o2);
+		if(shouldround)
+		{
+			fixed = _decimal_fix(ret, ctx);
+			Py_DECREF(ret);
+			if(!fixed)
+			{
+				return NULL;
+			}
+			return fixed;
+		}
+		return ret; */
 	}
 
 	Py_DECREF(o1);
@@ -3119,7 +3015,6 @@
     buf[0] = (self->sign & 1 ? '-' : '+');
     for (i = 0; i < max; i++) {
         if (i < self->ob_size)
-//            buf[i+1] = self->digits[i] + 48;
 			buf[i+1] = _limb_get_digit(self->limbs, self->ob_size, i) + '0';	/* SLOW */
 		else
             buf[i+1] = '0';
@@ -3163,7 +3058,6 @@
 
     for (i = 0; i < max; i++) {
         if (i < self->ob_size)
-//            res = res * 10 + self->digits[i];
 			res = res * 10 + _limb_get_digit(self->limbs, self->ob_size, i);	/* SLOW */
 		else
             res *= 10;
@@ -3192,8 +3086,6 @@
     long i;
     if (ISSPECIAL(self))
         return 1;
-//    for (i = 0; i < self->ob_size; i++)
-//        if (self->digits[i] != 0) return 1;
 
 	for(i=0;i<self->limb_count;i++)
 		if(self->limbs[i] != 0) return 1;
@@ -3536,105 +3428,6 @@
 	}
 	
 	return new;
-//    long ipos = 0;   /* start of integral digits */
-//    long dpos = -1;  /* decimal point location */
-//    long dend = len; /* end of integral/decimal digits (last digit+1) */
-//    char *p = str;
-//    char sign = 0;
-//    decimalobject *new;
-//    long exp = 0, i, ndigits;
-
-    /* optional sign */
-//    if (*p == '+') {
-//        ++p;
-//        ipos = 1;
-//    } else if (*p == '-') {
-//        ++p;
-//        ipos = 1;
-//        sign = 1;
-//    }
-
-//    do {
-//        if (*p == '.') {
-//            dpos = p-str;
-//        } else if (*p == 'e' || *p == 'E') {
-//            dend = p-str;
-//            if (dend == ipos || (dpos >= 0 && dend == ipos+1))
-                /* no digits between sign and E */
-//                goto err;
-//            ++p;
-//            break;
-//        } else if (!isdigit(*p)) {
-//            goto err;
-//        }
-//    } while (*++p);
-
-    /* exponential part or end of string */
-//    if (*p == 0) {
-//        if (ipos == dpos && dpos == dend-1)
-            /* no digits at all */
-//            goto err;
-//        goto calculate;
-//    } else if (*p == '-' || *p == '+') {
-//        ++p;
-//    }
-
-//    do {
-        /* optional exponential digits */
-//        if (!isdigit(*p))
-//            goto err;
-//    } while (*++p);
-
-//  calculate:
-//    if (dend < len)
-//        exp = atol(str + dend + 1);
-//    if (dpos >= 0)
-        /* specified fractional digits, reduce exp */
-//        exp -= dend - dpos - 1;
-
-    /* If it's not a zero, strip leading 0s */
-//    for (p = str+ipos; p-str < dend; ++p) {
-//        if (*p != '0') {
-            /* first nonzero digit */
-//            ipos = (p-str);
-//            goto finish;
-//        }
-//    }
-    /* it's a zero */
-//    dend = (dpos == ipos ? ipos+2 : ipos+1);
-
-//  finish:
-//    ndigits = dend - ipos - (dpos<0 ? 0 : 1);
-//    new = _new_decimalobj(type, ndigits, sign, exp);
-//    if (!new)
-//        return NULL;
-//    i = 0;
-//    for (p = str+ipos; p-str < dend; ++p) {
-//        if (*p == '.') continue;
-//        new->digits[i] = *p - 48;
-//        i++;
-//    }
-	
-//	long mult = 1;
-//	long limb = 0;
-//	for(i=0;i<new -> limb_count; i++)
-//			new->limbs[i] = 0;
-	
-//	for(i = dend - 1; i>= ipos; i--)
-//	{
-//			if(str[i] == '.') continue;
-//			assert(limb < new->limb_count);
-//			new->limbs[limb] += mult * (str[i] - '0');
-//
-//			mult *= 10;
-//			if(mult == BASE)
-//			{
-//					mult = 1;
-//					limb ++;
-//			}
-//	}
-	
-  //  return new;
 
   err:
     return handle_ConversionSyntax(type, ctx, "invalid literal for Decimal");
@@ -3773,7 +3566,7 @@
 		}
 
 		new->digits[i] = x;
-    }			//this loop will go out soon XXX
+    }			/* this loop will go out soon XXX */
 	
 	for(i = 0;i < new->limb_count;i++)
 			new->limbs[i] = 0;
@@ -3781,7 +3574,7 @@
 	long mult = 1;
 	long limb = 0;
 	new->limbs[0] = 0;
-	for(i = new->ob_size-1; i>=0; i--)	//limb[0] keeps least significant limb
+	for(i = new->ob_size-1; i>=0; i--)	/* limb[0] keeps least significant limb */
 	{
 		item = PyTuple_GET_ITEM(digtup, i);
 		long x;
@@ -4311,8 +4104,6 @@
 static PyObject *
 context_clear_flags(contextobject *self)
 {
-//    self->flags = 0;
-//	PyDict_Clear(self->flags);
 	int i;
 	for(i = 0;i<NUMSIGNALS;i++)
 		_set_flag(self->flags,i,0);
@@ -5209,7 +5000,7 @@
     else
         capitals = capitals & 1;
 
-//    if (rounding_dec == -1)
+/*    if (rounding_dec == -1) */
 	if(rounding_dec != NEVER_ROUND && rounding_dec != ALWAYS_ROUND)	/* XXX????*/
 		rounding_dec = PyDecimal_DefaultContext->rounding_dec;
 


More information about the Python-checkins mailing list