[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