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