[Python-checkins] r51654 - in sandbox/trunk/decimal-c: _decimal.c new_dt/power.decTest test_decimal.py

mateusz.rukowicz python-checkins at python.org
Wed Aug 30 22:30:36 CEST 2006


Author: mateusz.rukowicz
Date: Wed Aug 30 22:30:34 2006
New Revision: 51654

Modified:
   sandbox/trunk/decimal-c/_decimal.c
   sandbox/trunk/decimal-c/new_dt/power.decTest
   sandbox/trunk/decimal-c/test_decimal.py
Log:
Added special case to power functions. Upated test_decimal.py. Now *decTest are very the same to Cowlish except two tests that are 'extra feature'.


Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Wed Aug 30 22:30:34 2006
@@ -5960,8 +5960,85 @@
     if (use_exp) {
         decimalobject *tmp;
         contextobject *ctx2;
+        
+        /* check context */
         if (!check_ctx(self, ctx))
             return handle_InvalidContext(self->ob_type, ctx, NULL);
+
+        /* now check operands */ 
+        if (decimal_nonzero(self) && (
+                    self->ob_size > MAX_MATH ||
+                    exp_g_i(exp_add_i(self->exp, self->ob_size), MAX_MATH + 1) ||
+                    exp_l_i(exp_add_i(self->exp, self->ob_size), 2 * (1 - MAX_MATH))))
+            return handle_InvalidOperation(self->ob_type, ctx, "Operand range violation", NULL);
+
+        if (decimal_nonzero(other) && (
+                    other->ob_size > MAX_MATH ||
+                    exp_g_i(exp_add_i(other->exp, other->ob_size), MAX_MATH + 1) ||
+                    exp_l_i(exp_add_i(other->exp, other->ob_size), 2 * (1 - MAX_MATH))))
+            return handle_InvalidOperation(other->ob_type, ctx, "Operand range violation", NULL);
+        
+        /* special cases */
+        {
+            int i;
+            int special = 1;
+            if (!exp_eq_i(ADJUSTED(self), -1))
+                special = 0;
+            if (special)
+                for (i = 0 ; i < ctx->prec; i ++) {
+                    if (_limb_get_digit(self->limbs, self->ob_size, i) != 9) {
+                        special = 0;
+                        break;
+                    }
+                }
+
+            /* self is 0.999...99 */
+            if (special) {
+                /* 0 < other < 1 */
+                if (!(other->sign&1) && exp_le_i(ADJUSTED(other), -1) && decimal_nonzero(other)) {
+
+                    /* if round up then return 1 */
+                    if (ctx->rounding == ROUND_UP || ctx->rounding == ROUND_CEILING) {
+                        long limb = ctx->prec / LOG;
+                        long mul = (ctx->prec % LOG) - 1;
+                        
+                        if (handle_Inexact(ctx, NULL))
+                            return NULL;
+                        
+                        if (handle_Rounded(ctx, NULL))
+                            return NULL;
+                        
+                        ret = _NEW_decimalobj(ctx->prec, 0, exp_from_i(1 - ctx->prec));
+                        
+                        if (!ret)
+                            return NULL;
+
+                        for (i=0 ; i < ret->limb_count ;i ++) 
+                            ret->limbs[i] = 0;
+
+                        ret->limbs[limb] = 1;
+
+                        for (i = 0 ; i < mul ; i ++) 
+                            ret->limbs[limb] *= 10;
+
+                        return ret;
+                    }
+
+                    /* if round down then return self  */
+                    else if (ctx->rounding == ROUND_DOWN || ctx->rounding == ROUND_FLOOR){
+                        if (handle_Inexact(ctx, NULL))
+                            return NULL;
+
+                        if (handle_Rounded(ctx, NULL))
+                            return NULL;
+
+                        return _decimal_get_copy(self);
+                    }
+                }
+            }
+        }
+
+
         ctx2 = context_shallow_copy(ctx);
         if (!ctx2)
             return NULL;
@@ -5971,11 +6048,10 @@
         ctx2->clamp = 0;
         ctx2->rounding = ctx->rounding;
         ctx2->rounding_dec = ALWAYS_ROUND;
-        /* we take context precision or size of self if greater
-         * and add some constant */
+        /* we take context precision or size of self if greater and
+         * add some constant */
         ctx2->prec = ctx->prec > self->ob_size ? ctx->prec : self->ob_size;
         ctx2->prec += 14;
-        
         ret = _do_decimal__ln(self, ctx2);
         if (!ret) {
             Py_DECREF(ctx2);

Modified: sandbox/trunk/decimal-c/new_dt/power.decTest
==============================================================================
--- sandbox/trunk/decimal-c/new_dt/power.decTest	(original)
+++ sandbox/trunk/decimal-c/new_dt/power.decTest	Wed Aug 30 22:30:34 2006
@@ -689,6 +689,10 @@
 powx1065 power   '10'  '999999997' -> '1.00000000E+999999997' Rounded
 powx1066 power   '10'  '333333333' -> '1.00000000E+333333333' Rounded
 -- next two are integer-out-of range
+powx1183 power   '7'   '1000000000'  -> NaN Invalid_context
+powx1184 power   '7'   '1000000001'  -> NaN Invalid_context
+-- powx1186 power   '7'   '-1000000001' -> 1.38243630E-845098041 Inexact Rounded
+-- powx1187 power   '7'   '-1000000000' -> 9.67705411E-845098041 Inexact Rounded
 
 -- out-of-range edge cases
 powx1118 power  '10'  '-333333333'   -> 1E-333333333
@@ -1463,13 +1467,13 @@
 
 -- operand range violations
 powx4007  power 1             1.1E+999999  ->  1
--- powx4008  power 1             1.1E+1000000 ->  NaN Invalid_operation
+powx4008  power 1             1.1E+1000000 ->  NaN Invalid_operation
 powx4009  power 1.1E+999999   1.1          ->  Infinity Overflow Inexact Rounded
--- powx4010  power 1.1E+1000000  1.1          ->  NaN Invalid_operation
+powx4010  power 1.1E+1000000  1.1          ->  NaN Invalid_operation
 powx4011  power 1             1.1E-1999997 ->  1.00000000 Inexact Rounded
--- powx4012  power 1             1.1E-1999998 ->  NaN Invalid_operation
+powx4012  power 1             1.1E-1999998 ->  NaN Invalid_operation
 powx4013  power 1.1E-1999997  1.1          ->  0E-1000006 Underflow Inexact Rounded Clamped Subnormal
--- powx4014  power 1.1E-1999998  1.1          ->  NaN Invalid_operation
+powx4014  power 1.1E-1999998  1.1          ->  NaN Invalid_operation
 
 -- rounding modes -- power is sensitive
 precision:   7
@@ -1579,3 +1583,35 @@
 powx4328  power  1.000001 0.9999999  -> 1.000000   Inexact Rounded
 powx4329  power  1.000001 1.000000   -> 1.000001
 
+-- For x=prevfp(1)=0.99..99 (where the number of 9s is precision)
+--   power(x,y)=x when the rounding is down for any y in (0,1].
+rounding: floor
+powx4341  power  0.9999999 0          -> 1
+powx4342  power  0.9999999 1e-101     -> 0.9999999   Inexact Rounded
+powx4343  power  0.9999999 1e-95      -> 0.9999999   Inexact Rounded
+powx4344  power  0.9999999 1e-10      -> 0.9999999   Inexact Rounded
+powx4345  power  0.9999999 0.1        -> 0.9999999   Inexact Rounded
+powx4346  power  0.9999999 0.1234567  -> 0.9999999   Inexact Rounded
+powx4347  power  0.9999999 0.7        -> 0.9999999   Inexact Rounded
+powx4348  power  0.9999999 0.9999999  -> 0.9999999   Inexact Rounded
+powx4349  power  0.9999999 1.000000   -> 0.9999999
+--   power(x,y)=1 when the rounding is up for any y in (0,1].
+rounding: ceiling
+powx4361  power  0.9999999 0          -> 1
+powx4362  power  0.9999999 1e-101     -> 1.000000    Inexact Rounded
+powx4363  power  0.9999999 1e-95      -> 1.000000    Inexact Rounded
+powx4364  power  0.9999999 1e-10      -> 1.000000    Inexact Rounded
+powx4365  power  0.9999999 0.1        -> 1.000000    Inexact Rounded
+powx4366  power  0.9999999 0.1234567  -> 1.000000    Inexact Rounded
+powx4367  power  0.9999999 0.7        -> 1.000000    Inexact Rounded
+powx4368  power  0.9999999 0.9999999  -> 1.000000    Inexact Rounded
+powx4369  power  0.9999999 1.000000   -> 0.9999999
+
+-- For x=nextfp(0)
+--   power(x,y)=0 when the rounding is down for any y larger than 1.
+rounding: floor
+powx4382  power  1e-101    0          -> 1
+powx4383  power  1e-101    0.9999999  -> 1E-101 Underflow Subnormal Inexact Rounded
+powx4384  power  1e-101    1.000000   -> 1E-101 Subnormal
+powx4385  power  1e-101    1.000001   -> 0E-101 Underflow Subnormal Inexact Rounded Clamped
+powx4386  power  1e-101    2.000000   -> 0E-101 Underflow Subnormal Inexact Rounded Clamped

Modified: sandbox/trunk/decimal-c/test_decimal.py
==============================================================================
--- sandbox/trunk/decimal-c/test_decimal.py	(original)
+++ sandbox/trunk/decimal-c/test_decimal.py	Wed Aug 30 22:30:34 2006
@@ -50,7 +50,7 @@
     DefaultContext.traps = dict.fromkeys(Signals, 0)
     setcontext(DefaultContext)
 
-TESTDATADIR = 'decimaltestdata'
+TESTDATADIR = 'new_dt'
 if __name__ == '__main__':
     file = sys.argv[0]
 else:
@@ -1048,7 +1048,7 @@
         c = Context()
         e = pickle.loads(pickle.dumps(c))
         for k in ("prec", "Emin", "Emax", "capitals", "rounding",\
-                "_rounding_decision", "_clamp", "flags", "traps", "_ignored"):
+                "_rounding_decision", "_clamp", "flags", "traps", "_ignored_flags"):
             #v1 = vars(c)[k]
             v1 = c.__getattribute__(k)
             #v2 = vars(e)[k]


More information about the Python-checkins mailing list