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

mateusz.rukowicz python-checkins at python.org
Fri Jun 9 12:03:17 CEST 2006


Author: mateusz.rukowicz
Date: Fri Jun  9 12:03:15 2006
New Revision: 46768

Modified:
   sandbox/trunk/decimal-c/_decimal.c
Log:
Switched to 'limbs' instead of 'digits', some functions still calculates digits - this will be removed.


Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Fri Jun  9 12:03:15 2006
@@ -168,6 +168,27 @@
 	}
 }
 
+static void
+_limb_fill(long *self, long ndigits, long x)
+{
+	//TODO
+}
+
+static long
+_limb_get_digit(long *self, long ndigits, long i)
+{
+	long pos = ndigits - i - 1;
+	long limb = pos / LOG;
+	pos %= LOG;
+	long tmp = self[limb];
+	while(pos)
+	{
+			tmp/=10;
+			pos --;
+	}
+	return tmp%10;
+}
+
 /* helpful macros ************************************************************/
 
 /* if we later decide to call this module "squeaky" */
@@ -374,7 +395,10 @@
     res = _new_decimalobj(type, thing->ob_size, sign, 0);
     if (!res) return NULL;
     for (i = 0; i < thing->ob_size; i++)
-        res->digits[i] = thing->digits[i];
+        res->digits[i] = thing->digits[i];	/* DELETE */
+	
+	for (i = 0; i< res->limb_count;i++)
+		res->limbs[i] = thing->limbs[i];
     return res;
 }
 
@@ -478,6 +502,7 @@
             if (res) {
                 for (i = 0; i < ctx->prec; i++)
                     res->digits[i] = 9;
+				_limb_fill(res->limbs, ctx->prec, 9);
                 return res;
             }
         }
@@ -490,6 +515,7 @@
             if (res) {
                 for (i = 0; i < ctx->prec; i++)
                     res->digits[i] = 9;
+				_limb_fill(res->limbs, ctx->prec, 9);
                 return res;
             }
         }
@@ -666,10 +692,10 @@
 	i = 0;
 	while(new->limbs[i] >= BASE)
 	{
+			assert(i+1 < new->limb_count);
 			new->limbs[i] -= BASE;
 			new->limbs[i+1] ++;
 			i++;
-			assert(i+1 < new->limb_count);
 	}
     return new;
 }
@@ -700,9 +726,9 @@
         new->digits[i] = self->digits[i];
 	_limb_first_n_digits(self->limbs, self->ob_size, 0, new->limbs, prec);
 	
-    if (!new) return NULL;
     for (i = prec; i < self->ob_size; i++)
-        if (self->digits[i] > 0) {
+		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)
@@ -728,8 +754,9 @@
 {
     decimalobject *new;
     assert(expdiff > 0);
-    if (self->ob_size > prec && self->digits[prec] >= 5) {
-        new = _decimal_increment(tmp, 1, ctx);
+//    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);
         if (!new) return NULL;
         if (new->ob_size > prec) {
@@ -756,11 +783,11 @@
         tmp->digits[i] = self->digits[i];
 
 	last = _limb_first_n_digits(self->limbs, self->ob_size, 0, tmp->limbs, prec);
-	last = self->digits[prec];
 	assert(self->digits[prec] == last);
     if (last == 5) {
         for (i = prec+1; i < self->ob_size; i++) {
-            if (self->digits[i] != 0)
+			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 */
@@ -785,11 +812,13 @@
 	assert(last == self->digits[prec]);
     if (last == 5) {
         for (i = prec+1; i < self->ob_size; i++) {
-            if (self->digits[i] != 0)
+			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)
-            return tmp;
+//        if ((self->digits[prec-1] & 1) == 0)
+		if((_limb_get_digit(self->limbs, self->ob_size, i)&1) == 0)
+			return tmp;
     }
     return _do_round_half_up(self, prec, expdiff, ctx, tmp);
 }
@@ -875,6 +904,7 @@
         if (!new) return NULL;
         while (i--)
             new->digits[i] = 0;
+		_limb_fill(new->limbs, new->ob_size,0);
         
         if (handle_Rounded(ctx, NULL) != 0) {
             Py_DECREF(new);
@@ -889,6 +919,7 @@
         new->digits[0] = 0;
         for (i = 1; i < new->ob_size; i++)
             new->digits[i] = self->digits[i-1];
+		_limb_first_n_digits(self->limbs, self->ob_size, -1, new->limbs, new->ob_size);
         prec = 1;
     } else if (prec < 0) {
         new = _NEW_decimalobj(2, self->sign,
@@ -896,6 +927,7 @@
         if (!new) return NULL;
         new->digits[0] = 0;
         new->digits[1] = 1;
+		new->limbs[0] = 1;
         prec = 1;
     } else {
         new = _decimal_get_copy(self);
@@ -918,14 +950,17 @@
         for (i = new->ob_size; i < new2->ob_size; i++) {
             new2->digits[i] = 0;
         }
+
+		_limb_first_n_digits(new->limbs, new->ob_size, 0, new2->limbs, new2->ob_size);
         Py_DECREF(new);
         return new2;
     }
 
     /* Maybe all the lost digits are 0. */
     for (i = expdiff; i < self->ob_size; i++) {
-        if (self->digits[i] > 0)
-            goto no_way;
+//        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;
@@ -996,6 +1031,7 @@
         if (!ans)
             return NULL;
         ans->digits[0] = 0;
+		ans->limbs[0] = 0;
         return ans;
     }
 
@@ -1013,6 +1049,7 @@
             return NULL;
         ans->digits[0] = 0;
         ans->digits[1] = 1;
+		ans->limbs[0] = 1;
         digits = 1;
     } else {
         ans = _NEW_decimalobj(self->ob_size+1, self->sign, self->exp);
@@ -1021,6 +1058,7 @@
         for (i = 0; i < self->ob_size; i++)
             ans->digits[i+1] = self->digits[i];
         ans->digits[0] = 0;
+		_limb_first_n_digits(self->limbs, self->ob_size, -1, ans->limbs, ans->ob_size);
     }
 
     tmp = _decimal_round(ans, digits, ctx, rounding);
@@ -1807,7 +1845,7 @@
 }
 
 
-static PyObject *
+static PyObject *	/* TODO review that */
 _do_decimal_str(decimalobject *d, contextobject *context, int engineering)
 {
     char *outbuf;
@@ -1876,8 +1914,9 @@
     }
     if (engineering) { /* eng has no leading zeros */
         for (i = 0, j = 0; i < imax; i++) {
-            if (d->digits[j] == 0) {
-                j++;
+//            if (d->digits[j] == 0) {
+			if(_limb_get_digit(d->limbs, d->ob_size, j) == 0){
+				j++;
             } else {
                 break;
             }
@@ -1889,8 +1928,9 @@
             SANITY_CHECK(p);
             continue;
         } else {
-            p += sprintf(p, "%d", d->digits[j]);
-            SANITY_CHECK(p);
+//            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++;
         }
     }
@@ -2453,9 +2493,12 @@
     long i;
     if (ISSPECIAL(self))
         return 1;
-    for (i = 0; i < self->ob_size; i++)
-        if (self->digits[i] != 0) return 1;
-    return 0;
+//    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;
+	return 0;
 }
 
 
@@ -2877,7 +2920,7 @@
 	{
 		item = PyTuple_GET_ITEM(digtup, i);
 		long x;
-		if(PyInt_AsLong(item))
+		if(PyInt_Check(item))
 			x = PyInt_AsLong(item);
 		else if (PyLong_Check(item)) {
 			x = PyLong_AsLong(item);


More information about the Python-checkins mailing list