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

mateusz.rukowicz python-checkins at python.org
Fri Jul 7 21:45:47 CEST 2006


Author: mateusz.rukowicz
Date: Fri Jul  7 21:45:46 2006
New Revision: 50481

Modified:
   sandbox/trunk/decimal-c/_decimal.c
Log:
Exponents works ok now everywhere.


Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Fri Jul  7 21:45:46 2006
@@ -539,8 +539,12 @@
 }
 #ifdef BIG_EXP
 
+/* TODO this implementation assumes that every limb, which
+ * is not used is 0. Since it's not really fast, this will
+ * change */
 
-exp_t exp_from_i(long a) {
+static exp_t 
+exp_from_i(long a) {
     exp_t ret;
 
     memset(ret.limbs, 0, sizeof(long) * EXP_LIMB_COUNT);
@@ -557,7 +561,7 @@
     return ret;
 }
 
-int 
+static int 
 exp_sscanf(char *buf, exp_t *exp) {
     int len;
     long mul;
@@ -606,7 +610,7 @@
     return 1;
 }
 
-int
+static int
 exp_sprintf(char *buf, exp_t exp) {
     int written = 0;
     int tmp;
@@ -631,8 +635,47 @@
     return written;
 }
 
+/* must check errors with PyErr_Occurred() */
+static exp_t
+exp_from_pyobj(PyObject *a)
+{
+    if (PyInt_Check(a)) {
+        return exp_from_i(PyInt_AS_LONG(a));
+    }
+    else if (PyLong_Check(a)) {
+        char *bufer;
+        PyObject *strval;
+        exp_t ret;
+        Py_ssize_t buf_len = 0;
+        strval = PyObject_Str(a);
+
+        if (!strval)
+            return ret;
+
+        if (PyObject_AsCharBuffer(strval, (const char **)&bufer, &buf_len) == -1) {
+            Py_DECREF(strval);
+            return ret;
+        }
+        
+        if (exp_sscanf(bufer, &ret) != 1) {
+            Py_DECREF(strval);
+            PyErr_SetString(PyExc_TypeError, "exponent must be integer value.");
+            return ret;
+        }
+
+        Py_DECREF(strval);
+        return ret;
+    }
+
+    else {
+        exp_t ret;
+        PyErr_SetString(PyExc_TypeError, "exponent must be integer value.");
+        return ret;
+    }
+}
+
 /* there is no overflow checking !*/
-long
+static long
 exp_to_i(exp_t exp) {
     long mult;
     long i;
@@ -654,7 +697,16 @@
     return ret;
 }
 
-exp_t
+static PyObject*
+exp_to_pyobj(exp_t exp) 
+{
+    char bufer[LOG * EXP_LIMB_COUNT + 5];
+    exp_sprintf(bufer, exp);
+
+    return PyLong_FromString(bufer, 0, 10);
+}
+
+static exp_t
 exp_inp_add(exp_t *a, exp_t b) {
     if (a->sign == b.sign) {
         a->size = _limb_add(a->limbs, a->size * LOG, b.limbs, b.size * LOG, a->limbs);
@@ -688,7 +740,7 @@
     return *a;
 }
 
-exp_t
+static exp_t
 exp_inp_sub(exp_t *a, exp_t b) {
     exp_t tmp_b = b;
     tmp_b.sign ^= 1;
@@ -698,47 +750,47 @@
     return exp_inp_add(a, tmp_b);
 }
 
-exp_t
+static exp_t
 exp_add(exp_t a, exp_t b) {
     return exp_inp_add(&a, b); 
 }
 
-exp_t
+static exp_t
 exp_sub(exp_t a, exp_t b) {
     return exp_inp_sub(&a, b);
 }
 
-exp_t
+static exp_t
 exp_add_i(exp_t a, long b) {
     return exp_add(a, exp_from_i(b));
 }
 
-exp_t
+static exp_t
 exp_sub_i(exp_t a, long b) {
     return exp_sub(a, exp_from_i(b));
 }
 
-exp_t
+static exp_t
 exp_inp_add_i(exp_t *a, long b) {
     return exp_inp_add(a, exp_from_i(b));
 }
 
-exp_t
+static exp_t
 exp_inp_sub_i(exp_t *a, long b) {
     return exp_inp_sub(a, exp_from_i(b));
 }
 
-exp_t
+static exp_t
 exp_inc(exp_t *a) {
     return exp_inp_add(a, exp_from_i(1));
 }
 
-exp_t
+static exp_t
 exp_dec(exp_t *a) {
     return exp_inp_sub(a, exp_from_i(1));   
 }
 
-exp_t
+static exp_t
 exp_mul(exp_t a, exp_t b) {
     exp_t ret;
     memset(ret.limbs, 0, sizeof(long) *EXP_LIMB_COUNT);
@@ -749,12 +801,12 @@
     return ret;
 }
 
-exp_t
+static exp_t
 exp_mul_i(exp_t a, long b) {
     return exp_mul(a, exp_from_i(b));
 }
 
-exp_t
+static exp_t
 exp_div_i(exp_t a, long b, long *remainder) {
     exp_t ret;
     long i;
@@ -782,8 +834,7 @@
     return ret;
 }
 
-/* TODO */
-exp_t
+static exp_t
 exp_floordiv_i(exp_t a, long b) {
     long remainder;
     exp_t ret;
@@ -794,15 +845,14 @@
     return ret;
 }
 
-/* TODO */
-int
+static int
 exp_mod_i(exp_t a, long b) {
     long remainder;
     exp_div_i(a, b, &remainder);
     return remainder;
 }
 
-int 
+static int 
 exp_cmp(exp_t a, exp_t b) {
     int cmp;
     if (a.sign != b.sign) {
@@ -819,89 +869,93 @@
         return cmp;
 }
 
-int
+static int
 exp_cmp_i(exp_t a, long b) {
     return exp_cmp(a, exp_from_i(b));
 }
 
-int
+static int
 exp_g(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     return cmp == 1;
 }
 
-int
+static int
 exp_g_i(exp_t a, long b) {
     return exp_g(a, exp_from_i(b));
 }
 
-int
+static int
 exp_l(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     return cmp == -1;
 }
 
-int
+static int
 exp_l_i(exp_t a, long b) {
     return exp_l(a, exp_from_i(b));
 }
 
-int
+static int
 exp_eq(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     return cmp == 0;
 }
 
-int 
+static int 
 exp_eq_i(exp_t a, long b) {
     return exp_eq(a, exp_from_i(b));
 }
 
-int
+static int
 exp_ne(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     return cmp != 0;
 }
 
-int
+static int
 exp_ne_i(exp_t a, long b) {
     return exp_ne(a, exp_from_i(b));
 }
 
-int
+static int
 exp_ge(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     return (cmp == 1) || (cmp == 0);
 }
 
-int
+static int
 exp_ge_i(exp_t a, long b) {
     return exp_ge(a, exp_from_i(b));
 }
 
-int
+static int
 exp_le(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     return (cmp == -1) || (cmp == 0);
 }
 
-int exp_le_i(exp_t a, long b) {
+static int 
+exp_le_i(exp_t a, long b) {
     return exp_le(a, exp_from_i(b));
 }
 
-int exp_is_zero(exp_t a) {
+static int 
+exp_is_zero(exp_t a) {
     return a.limbs[0] == 0 && a.size == 1;
 }
 
-int exp_is_neg(exp_t a) {
+static int 
+exp_is_neg(exp_t a) {
     return !exp_is_zero(a) && a.sign == 1;
 }
 
-int exp_is_pos(exp_t a) {
+static int 
+exp_is_pos(exp_t a) {
     return !exp_is_zero(a) && a.sign == 0;
 }
 
-exp_t
+static exp_t
 exp_neg(exp_t a) {
     a.sign ^= 1;
     if (a.limbs[0] == 0 && a.size == 1)
@@ -909,7 +963,7 @@
     return a;
 }
 
-exp_t
+static exp_t
 exp_min(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     if (cmp == 1)
@@ -918,7 +972,7 @@
         return a;
 }
 
-exp_t
+static exp_t
 exp_max(exp_t a, exp_t b) {
     int cmp = exp_cmp(a, b);
     if(cmp == 1)
@@ -928,40 +982,41 @@
 }
 
 #else
-#define exp_add_i(exp, a)   ((exp) + (a))  // 
-#define exp_add(a, b)       ((a) + (b))     //
-#define exp_inc(a)          ((*a)++)        //
-#define exp_dec(a)          ((*a)--)        //
-#define exp_is_zero(a)      ((a) == 0)      //   
-#define exp_is_neg(a)       ((a) < 0)       //
-#define exp_is_pos(a)       ((a) > 0)       //
-#define exp_inp_add(a,b)    ((*(a)) += (b)) //
-#define exp_to_int(a)       (a)             //
-#define exp_to_i(a)         (a)             //
-#define exp_from_i(a)       (a)             //
-#define exp_sub_i(exp, a)   ((exp) - (a))   //
-#define exp_sub(a, b)       ((a) - (b))     //
-#define exp_g(a, b)         ((a) > (b))     //
-#define exp_l(a, b)         ((a) < (b))     //
-#define exp_ge(a, b)        ((a) >= (b))    //
-#define exp_eq(a, b)        ((a) == (b))    //
-#define exp_eq_i(a, b)      ((a) == (b))    //
-#define exp_ne(a, b)        ((a) != (b))    //
-#define exp_g_i(a, b)       ((a) > (b))     //
-#define exp_l_i(a, b)       ((a) < (b))     //
-#define exp_ge_i(a, b)      ((a) >= (b))    //
-#define exp_le_i(a, b)      ((a) <= (b))    //
+/* TODO a little mess here ;P */
+#define exp_add_i(exp, a)   ((exp) + (a))   
+#define exp_add(a, b)       ((a) + (b))     
+#define exp_inc(a)          ((*a)++)       
+#define exp_dec(a)          ((*a)--)        
+#define exp_is_zero(a)      ((a) == 0)         
+#define exp_is_neg(a)       ((a) < 0)       
+#define exp_is_pos(a)       ((a) > 0)       
+#define exp_inp_add(a,b)    ((*(a)) += (b)) 
+#define exp_to_int(a)       (a)             
+#define exp_to_i(a)         (a)             
+#define exp_from_i(a)       (a)             
+#define exp_sub_i(exp, a)   ((exp) - (a))   
+#define exp_sub(a, b)       ((a) - (b))     
+#define exp_g(a, b)         ((a) > (b))     
+#define exp_l(a, b)         ((a) < (b))     
+#define exp_ge(a, b)        ((a) >= (b))    
+#define exp_eq(a, b)        ((a) == (b))    
+#define exp_eq_i(a, b)      ((a) == (b))    
+#define exp_ne(a, b)        ((a) != (b))    
+#define exp_g_i(a, b)       ((a) > (b))     
+#define exp_l_i(a, b)       ((a) < (b))     
+#define exp_ge_i(a, b)      ((a) >= (b))    
+#define exp_le_i(a, b)      ((a) <= (b))    
 #define exp_mod_i(a, b)     ((a) % (b))
-#define exp_ge_i(a, b)      ((a) >= (b))    //
+#define exp_ge_i(a, b)      ((a) >= (b))    
 #define exp_floordiv_i(a,b) ((a) / (b) - ((a) % (b) && (a) < 0))
-#define exp_inp_sub(a, b)   ((*(a)) -= (b)) //
-#define exp_inp_sub_i(a, b) ((*(a)) -= (b)) //
-#define exp_sprintf(a, e)   (sprintf(a, "%d", e))   //
-#define exp_sscanf(a, e)    (sscanf(a, "%d", e))    //
-#define exp_min(a, b)       ((a) < (b) ? (a) : (b)) //
-#define exp_max(a, b)       ((a) > (b) ? (a) : (b)) //
-#define exp_neg(a)          (-(a))          //
-#define exp_mul_i(a, b)     ((a) * (b))     //
+#define exp_inp_sub(a, b)   ((*(a)) -= (b)) 
+#define exp_inp_sub_i(a, b) ((*(a)) -= (b)) 
+#define exp_sprintf(a, e)   (sprintf(a, "%d", e))   
+#define exp_sscanf(a, e)    (sscanf(a, "%d", e))    
+#define exp_min(a, b)       ((a) < (b) ? (a) : (b)) 
+#define exp_max(a, b)       ((a) > (b) ? (a) : (b)) 
+#define exp_neg(a)          (-(a))          
+#define exp_mul_i(a, b)     ((a) * (b))     
 #endif
 
 
@@ -2870,9 +2925,6 @@
 
         ret->limbs[0] = 0;
         ret->exp = exp_floordiv_i(self->exp, 2);
-//        ret->exp = self->exp / 2;
-//        if (self->exp < 0 && self->exp%2)
-//            ret->exp --;
         ret->sign = self->sign & 1;
 
         return ret;
@@ -2888,9 +2940,6 @@
         return NULL;
 
     expadd = exp_floordiv_i(tmp->exp, 2);
-//    expadd = tmp->exp/2;
-//    if (tmp->exp < 0 && tmp->exp % 2)
-//        expadd --;
     
     if (exp_mod_i(tmp->exp, 2)) {
         _limb_first_n_digits(self->limbs, self->ob_size, 0, tmp->limbs, tmp->ob_size);
@@ -2940,14 +2989,12 @@
         ans->limbs[0] = 819;
         ans->exp = exp_sub_i(ADJUSTED(tmp), 2);
         tmp2->limbs[0] = 259;
-//        tmp2->exp = -2;
         exp_inp_sub_i(&(tmp2->exp), 2);
     }
     else {
         ans->limbs[0] = 259;
         ans->exp = exp_add_i(tmp->exp, tmp->ob_size - 3);
         tmp2->limbs[0] = 819;
-//        tmp2->exp = -3;
         exp_inp_sub_i(&(tmp2->exp), 3);
     }
 
@@ -3031,7 +3078,6 @@
     ctx2->prec = firstprec + 1;
     if (exp_ne(prevexp, ADJUSTED(tmp2))) {
         _limb_first_n_digits(tmp2->limbs, tmp2->ob_size, 0, ans->limbs, ans->ob_size);
-//        ans->exp --;    
         exp_dec(&(ans->exp));
     }
     else {
@@ -3114,7 +3160,6 @@
         }
     }
 
-//    ans->exp += expadd;
     exp_inp_add(&(ans->exp), expadd);
     ctx2->rounding = rounding;
 
@@ -3214,7 +3259,6 @@
         if (_check_nans(self, NULL, ctx, &nan) != 0)
             return nan;
     }
-//    if (self->exp >= 0) {
     if (exp_is_pos(self->exp) || exp_is_zero(self->exp)) {
         Py_INCREF(self);
         return self;
@@ -3307,8 +3351,8 @@
         return PyInt_FromLong(0);
 
     /* XXX: Overflow? */
-    /* EXP TODO */
-    return PyInt_FromSsize_t(exp_to_i(ADJUSTED(self)));
+/*    return PyInt_FromSsize_t(exp_to_i(ADJUSTED(self))); */
+    return exp_to_pyobj(ADJUSTED(self));
 }
 
 
@@ -3328,9 +3372,16 @@
         PyTuple_SET_ITEM(digits, i, d);
     }
 
-    /* TODO EXP */
-    if(!ISINF(self))
-        res = Py_BuildValue("(bOn)", self->sign % 2, digits, exp_to_i(self->exp));
+    if(!ISINF(self)) {
+        PyObject *exp = exp_to_pyobj(self->exp);
+        
+        if (!exp) {
+            Py_DECREF(digits);
+            return NULL;
+        }
+        res = Py_BuildValue("(bOO)", self->sign % 2, digits, exp);
+        Py_DECREF(exp);
+    }
     else {
         inf = PyString_FromString("F");
         if (!inf) {
@@ -3406,7 +3457,7 @@
         *p++ = '-';
         SANITY_CHECK(p);
     }
-//    if (d->exp < 0 && d->exp >= -6) {
+
     if(exp_is_neg(d->exp) && exp_ge_i(d->exp, -6)) {        
         i = 0;
         *p++ = '0';
@@ -3438,7 +3489,6 @@
                 *p++ = '+';
             SANITY_CHECK(p);
 
-//            p += sprintf(p, "%d", roundexp);
             p += exp_sprintf(p, roundexp);
             SANITY_CHECK(p);
         }
@@ -3512,13 +3562,11 @@
     adjexp = exp_from_i(0);
     dotplace = exp_add_i(d->exp, d->ob_size);
     /* dotplace must be at most d->ob_size (no dot at all) and at last -5 (6 pre-zeros)*/
-//    if(dotplace >d->ob_size || dotplace <-5)
     if (exp_g_i(dotplace, d->ob_size) || exp_l_i(dotplace, -5))
     {
         /* ok, we have to put dot after 1 digit, that is dotplace = 1 
          * we compute adjexp from equation (1) */
         dotplace = exp_from_i(1);
-//        adjexp = -dotplace + d->exp + d->ob_size;
         adjexp = exp_add_i(exp_sub(d->exp,dotplace), d->ob_size);
     }
 
@@ -3531,17 +3579,13 @@
 
     /* now all we have to do, is to put it to the string =] */
 
-//    if(dotplace > d->ob_size)
     if (exp_g_i(dotplace, d->ob_size))
         extra_zeros = exp_to_i(exp_sub_i(dotplace, d->ob_size));
 
-//    if(dotplace <= 0)
     if (exp_le_i(dotplace, 0))
     {
         *p++ = '0';
         *p++ = '.';
-//        while(dotplace++ < 0)
-//            *p++ = '0';
         while (exp_l_i(dotplace, 0)) {
             exp_inc(&dotplace);
             *p++ = '0';
@@ -3778,7 +3822,6 @@
             ans2 = _decimal_get_copy(self);
             if (!ans2)
                 return NULL;
-            //ans2->exp = self->exp < other->exp ? self->exp : other->exp;
             ans2->exp = exp_min(self->exp, other->exp);
             ans1 = _NEW_decimalobj(1, sign, exp_from_i(0));
             if (!ans1) {
@@ -3864,7 +3907,6 @@
             if (divmod == 1 || divmod == 3) {
                 decimalobject *tmp;
                 exp_t exp;
-//                exp = self->exp < other->exp ? self->exp : other->exp;
                 exp = exp_min(self->exp, other->exp);
                 tmp = _decimal_rescale(self, exp, ctx, -1, 0);
 
@@ -3979,7 +4021,6 @@
          * expdiff >= (-exp - LOG)/ LOG */
         if (divmod) {
             assert(!(exp_mod_i(exp, LOG)));
-//            min_expdiff = (-exp - LOG)/ LOG;
             min_expdiff = exp_sub_i(exp_neg(exp), LOG);
             min_expdiff = exp_floordiv_i(min_expdiff, LOG);
             
@@ -3993,7 +4034,6 @@
                 significant_limbs, remainder, exp_to_i(min_expdiff)));
         result->limbs[significant_limbs] = 0;
 
-//        exp += expdiff * LOG + LOG;
         exp_inp_add(&exp, exp_add_i(exp_mul_i(expdiff, LOG), LOG));
         rlimbs = _limb_size(remainder, remainder_limbs);
         /* remainder non-zero */
@@ -4007,7 +4047,6 @@
             }
             
             if (!divmod) {
-//                exp -= LOG;
                 exp_inp_sub_i(&exp, LOG);
                 result->limb_count ++;
                 result->ob_size += LOG;
@@ -4066,7 +4105,6 @@
                 break;
             _limb_cut_one_digit(result->limbs, result->ob_size);
             result->ob_size --;
-//            result->exp ++;
             exp_inc(&(result->exp));
         }
 
@@ -4339,7 +4377,6 @@
     }
 
     shouldround = (ctx->rounding_dec == ALWAYS_ROUND);
-//    exp = (self->exp < other->exp ? self->exp : other->exp);
     exp = exp_min(self->exp, other->exp);
     if (ctx->rounding == ROUND_FLOOR &&
         (self->sign & 1) != (other->sign & 1))
@@ -4359,9 +4396,7 @@
         return res;
     }
     if (!decimal_nonzero(self)) {
-//        oexp = other->exp - ctx->prec - 1;
         oexp = exp_sub_i(other->exp, ctx->prec + 1);
-//        exp = (exp > oexp ? exp : oexp);
         exp = exp_max(exp, oexp);
         res = _decimal_rescale(other, exp, ctx, 0, 0);
         if (!res) return NULL;
@@ -4374,9 +4409,7 @@
         }            
     }
     if (!decimal_nonzero(other)) {
-//        oexp = self->exp - ctx->prec - 1;
         oexp = exp_sub_i(self->exp, ctx->prec + 1);
-//        exp = (exp > oexp ? exp : oexp);
         exp = exp_max(exp, oexp);
         res = _decimal_rescale(self, exp, ctx, 0, 0);
         if (!res) return NULL;
@@ -5503,14 +5536,12 @@
     if(e)            /* pretty obvious */
     {
         int ok;
-//        ok = sscanf(e+1,"%d", &exp);
         ok = exp_sscanf(e+1, &exp);
         if(ok!=1)
         {
             goto err;
         }
     }
-//    exp -= digits_after_dot;
     exp_inp_sub_i(&exp, digits_after_dot);
     new = _new_decimalobj(type, ndigits, sign, exp);
     if(!new)
@@ -6297,16 +6328,14 @@
 static PyObject *
 context_Etiny(contextobject *self)
 {
-    /* TODO EXP */
-    return PyInt_FromSsize_t(exp_to_i(ETINY(self)));
+    return exp_to_pyobj(ETINY(self));
 }
 
 
 static PyObject *
 context_Etop(contextobject *self)
 {
-    /* TODO EXP */
-    return PyInt_FromSsize_t(exp_to_i(ETOP(self)));
+    return exp_to_pyobj(ETOP(self));
 }
 
 
@@ -6536,16 +6565,27 @@
 }
 
 
-/* TODO EXP */
 static PyObject *
 context_reduce(contextobject *self)
 {
+    PyObject *Emin, *Emax, *ret;
+    Emin = exp_to_pyobj(self->Emin);
+    if (!Emin)
+        return NULL;
+    Emax = exp_to_pyobj(self->Emax);
+    if (!Emax) {
+        Py_DECREF(Emin);
+        return NULL;
+    }
     /* Yes, it seems to be as simple as that. */
-    return Py_BuildValue("(O(liiOOlliiO))", self->ob_type,
+    ret =  Py_BuildValue("(O(liiOOOOiiO))", self->ob_type,
                          self->prec, self->rounding,
                          self->rounding_dec, self->traps, self->flags,
-                         exp_to_i(self->Emin), exp_to_i(self->Emax), self->capitals,
+                         Emin, Emax, self->capitals,
                          self->clamp, self->ignored);
+    Py_DECREF(Emin);
+    Py_DECREF(Emax);
+    return ret;
 }
 
 
@@ -6940,6 +6980,8 @@
     char roundstr[20] = "ROUND_";
     char flags[250] = "["; /* 250 is enough for 12 error names of max. 17 chars */
     char traps[250] = "["; /* and commas inbetween. */
+    char Emin[LOG * EXP_LIMB_COUNT + 1];
+    char Emax[LOG * EXP_LIMB_COUNT + 1];
     long flaglen = 1, traplen = 1;
 
     switch (self->rounding) {
@@ -6987,9 +7029,12 @@
     traps[traplen-2] = ']';
     traps[traplen-1] = 0;
 
-    return PyString_FromFormat("Context(prec=%ld, rounding=%s, Emin=%ld, "
-                               "Emax=%ld, capitals=%d, flags=%s, traps=%s)",
-                               self->prec, roundstr, self->Emin, self->Emax,
+    exp_sprintf(Emax, self->Emax);
+    exp_sprintf(Emin, self->Emin);
+
+    return PyString_FromFormat("Context(prec=%ld, rounding=%s, Emin=%s, "
+                               "Emax=%s, capitals=%d, flags=%s, traps=%s)",
+                               self->prec, roundstr, Emin, Emax,
                                self->capitals, flags, traps);
 }
 
@@ -7004,6 +7049,7 @@
 }
 
 
+/* TODO take a closer look at refs when error */
 static PyObject *
 context_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
@@ -7011,8 +7057,7 @@
                              "traps", "flags", "Emin", "Emax",
                              "capitals", "_clamp", "_ignored_flags", 0};
     long prec = LONG_MIN;
-//    long Emin = LONG_MAX, Emax = LONG_MIN;
-    long TEmin, TEmax;
+    PyObject *TEmin = NULL, *TEmax = NULL;
     exp_t Emin, Emax;
     int rounding = -1, rounding_dec = -1, capitals = -1, clamp = 0;
     PyObject *pytraps = NULL, *pyflags = NULL, *pyignored = NULL;
@@ -7022,17 +7067,30 @@
     PyObject *_ignored = NULL;
     int i, j;
 
-    TEmin = LONG_MAX;
-    TEmax = LONG_MIN;
-    /* TODO EXP */
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|liiOOlliiO:Context", kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|liiOOOOiiO:Context", kwlist,
                                      &prec, &rounding, &rounding_dec, &pytraps,
                                      &pyflags, &TEmin, &TEmax, &capitals, &clamp,
                                      &pyignored))
         return NULL;
 
-    Emin = exp_from_i(TEmin);
-    Emax = exp_from_i(TEmax);
+    
+    if (!TEmin)
+        Emin = exp_from_i(LONG_MAX);
+    else {
+        Emin = exp_from_pyobj(TEmin);
+        if (PyErr_Occurred()) {
+            goto err;
+        }
+    }
+        
+    if (!TEmax)
+        Emax = exp_from_i(LONG_MIN);
+    else {
+        Emax = exp_from_pyobj(TEmax);
+        if (PyErr_Occurred()) {
+            goto err;
+        }
+    }
 
     if (pytraps == NULL) {
         _traps = PyDict_Copy(PyDecimal_DefaultContext->traps);
@@ -7177,8 +7235,6 @@
 
 static PyMemberDef context_members[] = {
     {"prec", T_LONG, OFF(prec), 0},
-//    {"Emin", T_LONG, OFF(Emin), 0},
-//    {"Emax", T_LONG, OFF(Emax), 0},
     {"capitals", T_INT, OFF(capitals), 0},
     {"rounding", T_INT, OFF(rounding), 0},
     {"_rounding_decision", T_INT, OFF(rounding_dec), 0},
@@ -7191,32 +7247,30 @@
 
 static PyObject *
 context_get_emax(contextobject *self) {
-    return PyInt_FromLong(exp_to_i(self->Emax));
+    return exp_to_pyobj(self->Emax);
 }
 
 
-/* TODO EXP */
 static int
 context_set_emax(contextobject *self, PyObject *value) {
-    long var = PyInt_AsLong(value);
+    exp_t tmp = exp_from_pyobj(value);
     if (PyErr_Occurred())
         return -1;
-    self->Emax = exp_from_i(var);
+    self->Emax = tmp;
     return 0;
 }
 
 static PyObject *
 context_get_emin(contextobject *self) {
-    return PyInt_FromLong(exp_to_i(self->Emin));
+    return exp_to_pyobj(self->Emin);
 }
 
-/* TODO EXP */
 static int
 context_set_emin(contextobject *self, PyObject *value) {
-    long var = PyInt_AsLong(value);
+    exp_t tmp = exp_from_pyobj(value);
     if (PyErr_Occurred())
         return -1;
-    self->Emin = exp_from_i(var);
+    self->Emin = tmp;
     return 0;
 }
 


More information about the Python-checkins mailing list