[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

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