[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

AltStyle によって変換されたページ (->オリジナル) /