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

mateusz.rukowicz python-checkins at python.org
Sat Aug 5 04:02:59 CEST 2006


Author: mateusz.rukowicz
Date: Sat Aug  5 04:02:58 2006
New Revision: 51121

Modified:
   sandbox/trunk/decimal-c/_decimal.c
Log:
Some minor fixes, trim function added.


Modified: sandbox/trunk/decimal-c/_decimal.c
==============================================================================
--- sandbox/trunk/decimal-c/_decimal.c	(original)
+++ sandbox/trunk/decimal-c/_decimal.c	Sat Aug  5 04:02:58 2006
@@ -2535,6 +2535,7 @@
     }
     
     /* strip trailing 0s from dup */
+    /* SLOW */
     while(_limb_get_digit(dup->limbs, dup->ob_size, dup->ob_size -1) == 0){
         _limb_cut_one_digit(dup->limbs,dup->ob_size);
         dup->ob_size --;
@@ -2544,6 +2545,49 @@
 }
 DECIMAL_UNARY_FUNC(normalize)
 
+/* strip trailing 0s that are right to the dot */
+static decimalobject *
+_do_decimal_trim(decimalobject *self, contextobject *ctx) {
+    decimalobject *new;
+    if (ISSPECIAL(self)) {
+        Py_INCREF(self);
+        return self;
+    }
+
+    if (!decimal_nonzero(self)) {
+        new = _NEW_decimalobj(1, self->sign, exp_from_i(0));
+        if (!new)
+            return NULL;
+        new->limbs[0] = 0;
+        return new;
+    }
+    new = _decimal_get_copy(self);
+    if (!new)
+        return NULL;
+
+
+    /* SLOW */
+    if (exp_le_i(new->exp, 0))
+        while (_limb_get_digit(new->limbs, new->ob_size, new->ob_size - 1) == 0 &&
+                exp_l_i(new->exp, 0)) {
+            _limb_cut_one_digit(new->limbs, new->ob_size);
+            new->ob_size --;
+            exp_inc(&(new->exp));
+        
+        }
+    else 
+        while (_limb_get_digit(new->limbs, new->ob_size, new->ob_size - 1) == 0) {
+            _limb_cut_one_digit(new->limbs, new->ob_size);
+            new->ob_size --;
+            exp_inc(&(new->exp));
+        }
+
+    return new;
+
+    
+}
+
+DECIMAL_UNARY_FUNC(trim)
 
 /* Quantize self so that its exponent is the same as the exponent of another. */
 static decimalobject *
@@ -4247,6 +4291,16 @@
     return (PyObject*) _do_decimal__divide(self, other, divmod, ctx);
 }
 
+static int *
+check_ctx(decimalobject *self, contextobject *ctx) {
+    
+    if (ctx->prec > MAX_MATH ||
+            exp_g_i(ctx->Emax, MAX_MATH) ||
+            exp_l_i(ctx->Emin,-1 * MAX_MATH))
+        return 0;
+        
+    return 1;
+}
 
 /* The idea is as follows, we need to calculate e^x (self = x),
  * we use series e^x = x^0/0! + x^1/1! + x^2/2! ... 
@@ -4537,13 +4591,13 @@
     if (!ctx)
         return NULL;
 
-    if (ctx->prec > MAX_MATH ||
-            exp_g_i(ctx->Emax, MAX_MATH) ||
-            exp_l_i(ctx->Emin,-1 * MAX_MATH))
-        handle_InvalidContext(self->ob_type, ctx, NULL);
+    if (!check_ctx(self, ctx))
+        return handle_InvalidContext(self->ob_type, ctx, NULL);
     return _do_decimal_exponent(self, ctx);
 }
 
+DECIMAL_UNARY_FUNC(exp);
+
 int ln_lookup[] = {9016,  8652,  8316,  8008,  7724,  7456,  7208,
     6972,  6748,  6540,  6340,  6148,  5968,  5792,  5628,  5464,  5312,
     5164,  5020,  4884,  4748,  4620,  4496,  4376,  4256,  4144,  4032,
@@ -4780,6 +4834,8 @@
 
 static PyObject *
 _do_decimal_ln(decimalobject *self, contextobject *ctx) {
+    if (!check_ctx(self, ctx))
+        return handle_InvalidContext(self->ob_type, ctx, NULL);
     return _do_decimal__ln(self, ctx);
 }
 
@@ -4797,6 +4853,8 @@
     if (!ctx)
         return NULL;
 
+    if (!check_ctx(self, ctx))
+        return handle_InvalidContext(self->ob_type, ctx, NULL);
     if (ISSPECIAL(self)) {
         decimalobject *nan;
         if (_check_nans(self, NULL, ctx, &nan) != 0)
@@ -4896,6 +4954,7 @@
             }
             Py_DECREF(tmp);
         }
+        Py_DECREF(ctx2);
 
         /* log10 = ln(self)/ln(10) */
         ret = _do_decimal__divide(a, ln10, 0, ctx);
@@ -5029,7 +5088,7 @@
     {"_ln",             (PyCFunction)decimal__ln,
     METH_VARARGS | METH_KEYWORDS,
     PyDoc_STR("TODO")},
-    {"exp",             (PyCFunction)decimal_exponent,
+    {"exp",             (PyCFunction)decimal_exp,
     METH_VARARGS | METH_KEYWORDS,
     PyDoc_STR("TODO")},
     {"_exponent",       (PyCFunction)decimal_exponent,
@@ -5071,6 +5130,9 @@
      METH_VARARGS | METH_KEYWORDS,
      PyDoc_STR("Normalize- strip trailing 0s, change anything equal"
                "to 0 to 0e0")},
+    {"trim",            (PyCFunction)decimal_trim,
+     METH_VARARGS | METH_KEYWORDS,
+     PyDoc_STR("TODO")},
     {"quantize",        (PyCFunction)decimal_quantize,
      METH_VARARGS | METH_KEYWORDS,
      PyDoc_STR("Quantize self so its exponent is the same as that of exp.\n\n"
@@ -5809,6 +5871,8 @@
     /* non-integer case */
     /* we calculate it using exp(ln(self) * other) */
     if (use_exp) {
+        if (!check_ctx(self, ctx))
+            return handle_InvalidContext(self->ob_type, ctx, NULL);
         decimalobject *tmp;
         contextobject *ctx2;
         ctx2 = context_shallow_copy(ctx);
@@ -7400,6 +7464,7 @@
 CONTEXT_BINARY_FUNC(min, min)
 CONTEXT_BINARY_FUNC(max, max)
 CONTEXT_UNARY_FUNC(normalize, normalize)
+CONTEXT_UNARY_FUNC(trim, trim)
 CONTEXT_BINARY_FUNC(remainder_near, remainder_near)
 CONTEXT_UNARY_FUNC(sqrt, sqrt)
 CONTEXT_UNARY_FUNC(to_eng_string, to_eng_string)
@@ -7915,6 +7980,8 @@
      METH_VARARGS},
     {"normalize",       (PyCFunction)context_normalize,
      METH_O},
+    {"trim",            (PyCFunction)context_trim,
+     METH_O},
     {"plus",            (PyCFunction)context_plus,
      METH_O},
     {"power",           (PyCFunction)context_power,


More information about the Python-checkins mailing list