[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

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