Author: Amaury Forgeot d'Arc <[email protected]>
Branch: decimal-libmpdec
Changeset: r73807:a75ccd9fcb14
Date: 2014-09-30 10:38 +0200
http://bitbucket.org/pypy/pypy/changeset/a75ccd9fcb14/

Log:    More methods

diff --git a/pypy/module/_decimal/interp_context.py 
b/pypy/module/_decimal/interp_context.py
--- a/pypy/module/_decimal/interp_context.py
+++ b/pypy/module/_decimal/interp_context.py
@@ -306,6 +306,19 @@
                             ctx, status_ptr)
         return w_result
 
+    def apply_w(self, space, w_v):
+        from pypy.module._decimal import interp_decimal
+        w_a = interp_decimal.convert_op_raise(space, self, w_v)
+        return w_a.apply(space, self)
+
+    def copy_abs_w(self, space, w_v):
+        from pypy.module._decimal import interp_decimal
+        w_a = interp_decimal.convert_op_raise(space, self, w_v)
+        w_result = interp_decimal.W_Decimal.allocate(space)
+        with self.catch_status(space) as (ctx, status_ptr):
+            rmpdec.mpd_qcopy_abs(w_result.mpd, w_a.mpd, status_ptr)
+        return w_result
+
 def descr_new_context(space, w_subtype, __args__):
     w_result = space.allocate_instance(W_Context, w_subtype)
     W_Context.__init__(w_result, space)
@@ -338,6 +351,19 @@
         return w_result
     return interp2app(func_w)
 
+def make_binary_method_noctx(mpd_func_name):
+    mpd_func = getattr(rmpdec, mpd_func_name)
+    @unwrap_spec(w_context=W_Context)
+    @func_renamer('descr_%s' % mpd_func_name)
+    def func_w(space, w_context, w_x, w_y):
+        from pypy.module._decimal import interp_decimal
+        w_a, w_b = interp_decimal.convert_binop_raise(
+            space, w_context, w_x, w_y)
+        w_result = interp_decimal.W_Decimal.allocate(space)
+        mpd_func(w_result.mpd, w_a.mpd, w_b.mpd)
+        return w_result
+    return interp2app(func_w)
+
 def make_bool_method(mpd_func_name):
     mpd_func = getattr(rmpdec, mpd_func_name)
     @unwrap_spec(w_context=W_Context)
@@ -430,6 +456,13 @@
     is_nan=make_bool_method_noctx('mpd_isnan'),
     is_qnan=make_bool_method_noctx('mpd_isqnan'),
     is_snan=make_bool_method_noctx('mpd_issnan'),
+    # Functions with a single decimal argument
+    _apply=interp2app(W_Context.apply_w),
+    apply=interp2app(W_Context.apply_w),
+    copy_abs=interp2app(W_Context.copy_abs_w),
+    # Functions with two decimal arguments
+    compare_total = make_binary_method_noctx('mpd_compare_total'),
+    compare_total_mag = make_binary_method_noctx('mpd_compare_total_mag'),
     )
 
 
diff --git a/pypy/module/_decimal/interp_decimal.py 
b/pypy/module/_decimal/interp_decimal.py
--- a/pypy/module/_decimal/interp_decimal.py
+++ b/pypy/module/_decimal/interp_decimal.py
@@ -544,6 +544,18 @@
                                       w_workctx.ctx, status_ptr)
         return w_result
 
+    def quantize_w(self, space, w_exp, w_rounding=None, w_context=None):
+        context = interp_context.ensure_context(space, w_context)
+        w_workctx = context.copy_w(space)
+        if not space.is_none(w_rounding):
+            w_workctx.set_rounding(space, w_rounding)
+        w_a, w_b = convert_binop_raise(space, context, self, w_exp)
+        w_result = W_Decimal.allocate(space)
+        with context.catch_status(space) as (ctx, status_ptr):
+            rmpdec.mpd_qquantize(w_result.mpd, w_a.mpd, w_b.mpd,
+                                 w_workctx.ctx, status_ptr)
+        return w_result
+
     # Ternary arithmetic functions, optional context arg
     def fma_w(self, space, w_other, w_third, w_context=None):
         context = interp_context.ensure_context(space, w_context)
@@ -1169,6 +1181,7 @@
     min = make_binary_method('mpd_qmin'),
     min_mag = make_binary_method('mpd_qmin_mag'),
     next_toward = make_binary_method('mpd_qnext_toward'),
+    quantize = interp2app(W_Decimal.quantize_w),
     remainder_near = make_binary_method('mpd_qrem_near'),
     logical_and = make_binary_method('mpd_qand'),
     logical_or = make_binary_method('mpd_qor'),
diff --git a/pypy/module/_decimal/test/test_decimal.py 
b/pypy/module/_decimal/test/test_decimal.py
--- a/pypy/module/_decimal/test/test_decimal.py
+++ b/pypy/module/_decimal/test/test_decimal.py
@@ -330,6 +330,32 @@
         assert str(nc.create_decimal(Decimal('NaN12345'))) == 'NaN'
         assert nc.flags[InvalidOperation]
 
+    def test_quantize(self):
+        Decimal = self.decimal.Decimal
+        Context = self.decimal.Context
+        InvalidOperation = self.decimal.InvalidOperation
+
+        c = Context(Emax=99999, Emin=-99999)
+        self.assertEqual(
+            Decimal('7.335').quantize(Decimal('.01')),
+            Decimal('7.34')
+        )
+        self.assertEqual(
+            Decimal('7.335').quantize(Decimal('.01'),
+                                      rounding=self.decimal.ROUND_DOWN),
+            Decimal('7.33')
+        )
+        self.assertRaises(
+            InvalidOperation,
+            Decimal("10e99999").quantize, Decimal('1e100000'), context=c
+        )
+
+        c = Context()
+        d = Decimal("0.871831e800")
+        x = d.quantize(context=c, exp=Decimal("1e797"),
+                       rounding=self.decimal.ROUND_DOWN)
+        self.assertEqual(x, Decimal('8.71E+799'))
+
     def test_complex(self):
         Decimal = self.decimal.Decimal
         d = Decimal("2.34")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to