[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