[pypy-commit] pypy decimal-libmpdec: Add Decimal.to_integral*()

amauryfa noreply at buildbot.pypy.org
Wed May 21 00:23:53 CEST 2014


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: decimal-libmpdec
Changeset: r71622:7b1c4d62bf95
Date: 2014-05-19 00:20 +0200
http://bitbucket.org/pypy/pypy/changeset/7b1c4d62bf95/

Log:	Add Decimal.to_integral*()

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
@@ -313,6 +313,35 @@
                                   status_ptr)
         return w_result
 
+    # Unary arithmetic functions, optional context arg
+
+    def to_integral_w(self, space, 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_result = W_Decimal.allocate(space)
+        with context.catch_status(space) as (ctx, status_ptr):
+            # We round with the temporary context, but set status and
+            # raise errors on the global one.
+            rmpdec.mpd_qround_to_int(w_result.mpd, self.mpd,
+                                     w_workctx.ctx, status_ptr)
+        return w_result
+        
+    def to_integral_exact_w(self, space, 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_result = W_Decimal.allocate(space)
+        with context.catch_status(space) as (ctx, status_ptr):
+            # We round with the temporary context, but set status and
+            # raise errors on the global one.
+            rmpdec.mpd_qround_to_intx(w_result.mpd, self.mpd,
+                                      w_workctx.ctx, status_ptr)
+        return w_result
+        
+
     # Boolean functions
     def is_qnan_w(self, space):
         return space.wrap(bool(rmpdec.mpd_isqnan(self.mpd)))
@@ -690,6 +719,10 @@
     __rmod__ = interp2app(W_Decimal.descr_rmod),
     __rdivmod__ = interp2app(W_Decimal.descr_rdivmod),
     __rpow__ = interp2app(W_Decimal.descr_rpow),
+    # Unary arithmetic functions, optional context arg
+    to_integral = interp2app(W_Decimal.to_integral_w),
+    to_integral_value = interp2app(W_Decimal.to_integral_w),
+    to_integral_exact = interp2app(W_Decimal.to_integral_exact_w),
     #
     copy_sign = interp2app(W_Decimal.copy_sign_w),
     is_qnan = interp2app(W_Decimal.is_qnan_w),
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
@@ -758,3 +758,35 @@
         d = Decimal( (1, (0, 2, 7, 1), 'F') )
         assert d.as_tuple() == (1, (0,), 'F')
 
+    def test_c_integral(self):
+        Decimal = self.decimal.Decimal
+        Inexact = self.decimal.Inexact
+        localcontext = self.decimal.localcontext
+        ROUND_UP = self.decimal.ROUND_UP
+
+        x = Decimal(10)
+        assert x.to_integral() == 10
+        raises(TypeError, x.to_integral, '10')
+        raises(TypeError, x.to_integral, 10, 'x')
+        raises(TypeError, x.to_integral, 10)
+
+        assert x.to_integral_value() == 10
+        raises(TypeError, x.to_integral_value, '10')
+        raises(TypeError, x.to_integral_value, 10, 'x')
+        raises(TypeError, x.to_integral_value, 10)
+
+        assert x.to_integral_exact() == 10
+        raises(TypeError, x.to_integral_exact, '10')
+        raises(TypeError, x.to_integral_exact, 10, 'x')
+        raises(TypeError, x.to_integral_exact, 10)
+
+        with localcontext() as c:
+            x = Decimal("99999999999999999999999999.9").to_integral_value(ROUND_UP)
+            assert x == Decimal('100000000000000000000000000')
+
+            x = Decimal("99999999999999999999999999.9").to_integral_exact(ROUND_UP)
+            assert x == Decimal('100000000000000000000000000')
+
+            c.traps[Inexact] = True
+            raises(Inexact, Decimal("999.9").to_integral_exact, ROUND_UP)
+


More information about the pypy-commit mailing list