Index: Lib/decimal.py =================================================================== --- Lib/decimal.py (revision 59523) +++ Lib/decimal.py (working copy) @@ -1454,6 +1454,10 @@ def __int__(self): """Converts self to an int, truncating if necessary.""" + return self.__trunc__() + + def __trunc__(self): + """Truncates self to an int.""" if self._is_special: if self._isnan(): context = getcontext() @@ -1465,7 +1469,24 @@ return s*int(self._int)*10**self._exp else: return s*int(self._int[:self._exp] or '0') + + def __floor__(self): + """Finds the greatest int <= self.""" + return trunc(self._rescale(0, ROUND_FLOOR)) + def __ceil__(self): + """Finds the least int >= self.""" + return trunc(self._rescale(0, ROUND_CEILING)) + + def __round__(self, ndigits:_numbers.Integral=None): + """Rounds self to ndigits decimal places, defaulting to 0. + + If ndigits is omitted or None, returns an int, otherwise a + Decimal. Rounds half toward even.""" + if ndigits is None: + return trunc(self._rescale(0, ROUND_HALF_EVEN)) + return self._rescale(-ndigits, ROUND_HALF_EVEN) + def _fix_nan(self, context): """Decapitate the payload of a NaN to fit the context""" payload = self._int Index: Lib/numbers.py =================================================================== --- Lib/numbers.py (revision 59523) +++ Lib/numbers.py (working copy) @@ -43,7 +43,6 @@ Inexact.register(complex) Inexact.register(float) -# Inexact.register(decimal.Decimal) class Complex(Number): @@ -274,7 +273,6 @@ return +self Real.register(float) -# Real.register(decimal.Decimal) class Rational(Real, Exact): Index: Lib/test/test_decimal.py =================================================================== --- Lib/test/test_decimal.py (revision 59523) +++ Lib/test/test_decimal.py (working copy) @@ -27,6 +27,7 @@ import unittest import glob +import math import os, sys import pickle, copy from decimal import * @@ -824,7 +825,45 @@ self.assertEqual(-Decimal(45), Decimal(-45)) # - self.assertEqual(abs(Decimal(45)), abs(Decimal(-45))) # abs + def test_trunc(self): + self.assertEqual(int, type(trunc(Decimal("17.5")))) + self.assertEqual(17, trunc(Decimal("17"))) + self.assertEqual(17, trunc(Decimal("17.0001"))) + self.assertEqual(17, trunc(Decimal("17.999999"))) + self.assertEqual(-17, trunc(Decimal("-17.999999"))) + self.assertEqual(10**30, trunc(Decimal("1e30"))) + def test_floor(self): + self.assertEqual(int, type(math.floor(Decimal("17.1")))) + self.assertEqual(17, math.floor(Decimal("17"))) + self.assertEqual(17, math.floor(Decimal("17.0001"))) + self.assertEqual(17, math.floor(Decimal("17.999999"))) + self.assertEqual(-18, math.floor(Decimal("-17.0001"))) + self.assertEqual(10**30, math.floor(Decimal("1e30"))) + + def test_ceil(self): + self.assertEqual(int, type(math.ceil(Decimal("17.1")))) + self.assertEqual(17, math.ceil(Decimal("17"))) + self.assertEqual(18, math.ceil(Decimal("17.0001"))) + self.assertEqual(18, math.ceil(Decimal("17.999999"))) + self.assertEqual(-17, math.ceil(Decimal("-17.0001"))) + self.assertEqual(10**30, math.ceil(Decimal("1e30"))) + + def test_round(self): + self.assertEqual(int, type(round(Decimal("17.5")))) + self.assertEqual(Decimal, type(round(Decimal("17"), 0))) + + self.assertEqual(18, round(Decimal("17.5"))) + self.assertEqual(16, round(Decimal("16.5"))) + self.assertEqual(17, round(Decimal("17.4"))) + self.assertEqual(10**30, round(Decimal("1e30"))) + + self.assertEqual(Decimal("17.5"), round(Decimal("17.5"), 1)) + self.assertEqual(Decimal("1.2e2"), round(Decimal("123.45"), -1)) + self.assertEqual(Decimal("1.200"), round(Decimal("1.2"), 3)) + self.assertEqual(Decimal("1" + "0"*30), round(Decimal("1e30"), 0)) + + # The following are two functions used to test threading in the next class def thfunc1(cls):