[Python-checkins] r46833 - sandbox/trunk/decimal-c/_decimal.c
mateusz.rukowicz
python-checkins at python.org
Sat Jun 10 22:50:17 CEST 2006
Author: mateusz.rukowicz
Date: Sat Jun 10 22:50:16 2006
New Revision: 46833
Modified:
sandbox/trunk/decimal-c/_decimal.c
Log:
Another bugs fixed, compare now works well.
Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c (original)
+++ sandbox/trunk/decimal-c/_decimal.c Sat Jun 10 22:50:16 2006
@@ -321,8 +321,10 @@
#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)
+#define ISINF(op) ( ( (op)->sign == SIGN_POSINF || (op)->sign == SIGN_NEGINF) ? \
+ ((op)->sign == SIGN_POSINF ? 1 : -1) : 0 )
+
/* Exponent calculations */
/* XXX: overflow checking? */
@@ -380,6 +382,7 @@
#define S_UNDERFLOW 6
#define S_SUBNORMAL 7
+/* WTF ?? */
/* Other conditions. If they occur and raise an exception,
it will be InvalidOperation. Also, context->flags, ->traps and
->ignored will only contain entries for the signals defined above.
@@ -1476,6 +1479,14 @@
/* comparisons with NaN always report self>other */
return 1;
}
+
+ if(ISINF(self) || ISINF(other))
+ {
+ if(ISINF(self) == ISINF(other))
+ return 0;
+ else
+ return ISINF(self) > ISINF(other) ? 1 : -1 ;
+ }
}
/* If both are 0, sign comparison isn't correct. */
@@ -1515,12 +1526,14 @@
next:
/* Adjusted sizes are not equal. */
- if (adj1 > adj2 && self->digits[0] != 0)
- return 1 - 2*(self->sign & 1); /* 0 -> 1, 1 -> -1 */
- else if (adj1 < adj2 && other->digits[0] != 0)
- return 1 - 2*(other->sign & 1);
+// 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);
- ctx2 = context_shallow_copy(ctx);
+ ctx2 = context_copy(ctx);
if (!ctx2) return 0; /* error */
ctx2->rounding = ROUND_UP; /* away from 0 */
@@ -1531,7 +1544,7 @@
ans = _do_decimal_subtract(self, other, ctx2);
if (!ans) return 0;
- if (decimal_nonzero(ans))
+ if (!decimal_nonzero(ans))
i = 0;
else if (ans->sign & 1)
i = -1;
@@ -1968,6 +1981,7 @@
char *p, *end;
int roundexp, i;
+ end = &outbuf[FORMAT_SIZE-1];
p = outbuf;
if (d->sign & 1) {
*p++ = '-';
@@ -1975,15 +1989,25 @@
}
if (d->exp < 0 && d->exp >= -6) {
/* figure out the right number of digits */
- i = sprintf(p, "0.%0*d", abs(d->exp), 0);
+// i = sprintf(p, "0.%0*d", abs(d->exp), 0);
/* and write those as zeros */
- for (; i > 0; i--) {
- *p++ = '0';
- }
+// for (; i > 0; i--) {
+// *p++ = '0';
+// }
+ i = 0;
+ *p++ = '0';
+ *p++ = '.';
+ for(;i<abs(d->exp);i++)
+ *p++ = '0';
SANITY_CHECK(p);
} else {
- roundexp = ((d->exp - 1)/3 + 1) * 3; /* nearest gt mult of 3 */
- if (roundexp != d->exp) {
+// roundexp = ((d->exp - 1)/3 + 1) * 3; /* nearest gt mult of 3 */
+ roundexp = d->exp;
+ while(roundexp%3)
+ roundexp ++;
+ if (roundexp != d->exp) {
+ *p++ = '0';
+ *p++ = '.';
for (i = 0; i < (roundexp - d->exp); i++)
*p++ = '0';
SANITY_CHECK(p);
@@ -2005,6 +2029,8 @@
SANITY_CHECK(p);
}
}
+ *p++ = 0;
+ p = &outbuf[0];
return PyString_FromString(p);
}
@@ -2084,11 +2110,14 @@
{
adjexp --;
dotplace ++;
- extra_zeros ++;
+// extra_zeros ++;
}
/* now all we have to do, is to put it to the string =] */
+ if(dotplace > d->ob_size)
+ extra_zeros = dotplace - d->ob_size;
+
if(dotplace <= 0)
{
*p++ = '0';
@@ -2705,7 +2734,7 @@
static decimalobject *
_do_decimal_negative(decimalobject *self, contextobject *ctx)
{
- int sign = 0;
+ int sign = self->sign;
decimalobject *tmp, *res;
if (ISSPECIAL(self)) {
@@ -3100,6 +3129,7 @@
char *last_digit = 0;
char *dot = 0;
char *e = 0;
+ int any_digit = 0;
char *c;
long i;
decimalobject *new;
@@ -3133,7 +3163,7 @@
else if(*c == '.')
{
- if(dot)
+ if(dot || e)
goto err;
dot = c;
}
@@ -3148,6 +3178,8 @@
}
else
{
+ if(!e)
+ any_digit = 1;
if(dot && !e)
digits_after_dot ++;
@@ -3158,6 +3190,8 @@
}
}
} /* we now are pretty sure, that string is properly formated */
+ if(!any_digit)
+ goto err;
if(!first_digit)
{
zero = 1;
@@ -3180,9 +3214,21 @@
assert(isdigit(*c) || *c == '.');
}
}
+
+ if(!ndigits)
+ {
+ goto err;
+ }
if(e) /* pretty obvious */
- exp = atol(e+1);
+ {
+ int ok;
+ ok = sscanf(e+1,"%d", &exp);
+ if(ok!=1)
+ {
+ goto err;
+ }
+ }
exp -= digits_after_dot;
new = _new_decimalobj(type, ndigits, sign, exp);
@@ -3583,7 +3629,11 @@
return decimal_from_long(type, x);
}
- ctx = getcontext();
+ if(context)
+ ctx = context;
+ else
+ ctx = getcontext();
+
if (!ctx) return NULL;
if (PyLong_Check(value))
@@ -4135,7 +4185,7 @@
static char *kwlist[] = {"a", 0};
decimalobject *a;
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &a))
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "O:_apply", kwlist, &a))
return NULL;
if(!PyDecimal_Check(a))
@@ -4264,12 +4314,13 @@
static PyObject *
-context_to_sci_string(contextobject *self, PyObject *args)
+context_to_sci_string(contextobject *self, PyObject *args, PyObject *kwds)
{
PyObject *a, *res;
decimalobject *dec_a = NULL;
+ static char *kwlist[] = {"a", 0};
- if (!PyArg_ParseTuple(args, "O:to_sci_string", &a))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:to_sci_string", kwlist, &a))
return NULL;
dec_a = (decimalobject *)_convert_to_decimal(
@@ -4277,8 +4328,7 @@
if (dec_a == NULL)
return NULL;
- /* XXX: default third argument? */
- res = _do_decimal_str(dec_a, self, -1);
+ res = _do_decimal_str(dec_a, self, 0);
Py_DECREF(dec_a);
return res;
}
@@ -4627,7 +4677,7 @@
{"to_integral", (PyCFunction)context_to_integral,
METH_O},
{"to_sci_string", (PyCFunction)context_to_sci_string,
- METH_O},
+ METH_VARARGS | METH_KEYWORDS},
{"_ignore_all_flags", (PyCFunction)context_ignore_all_flags,
METH_NOARGS},
{"_ignore_flags", (PyCFunction)context_ignore_flags,
More information about the Python-checkins
mailing list