summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2009-10-29 12:23:02 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2009-10-29 12:23:02 (GMT)
commita2d1fe0b843b27130d0e3194ac2f517692e89c85 (patch)
tree6bee99768ef3f8354d19623705388b1e4d85bb25
parentcb9285cd3797aa6d33c8fad5f23125d74b4d4487 (diff)
downloadcpython-a2d1fe0b843b27130d0e3194ac2f517692e89c85.zip
cpython-a2d1fe0b843b27130d0e3194ac2f517692e89c85.tar.gz
cpython-a2d1fe0b843b27130d0e3194ac2f517692e89c85.tar.bz2
Merged revisions 75943-75945 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r75943 | mark.dickinson | 2009-10-29 11:09:09 +0000 (Thu, 29 Oct 2009) | 1 line Fix duplicate test numbers in extra.decTest ........ r75944 | mark.dickinson | 2009-10-29 12:04:00 +0000 (Thu, 29 Oct 2009) | 3 lines Issue #7233: A number of two-argument Decimal methods were failing to accept ints and longs for the second argument. ........ r75945 | mark.dickinson | 2009-10-29 12:11:18 +0000 (Thu, 29 Oct 2009) | 4 lines Issue #7233: Fix Decimal.shift and Decimal.rotate methods for arguments with more digits than the current context precision. Bug reported by Stefan Krah. ........
-rw-r--r--Lib/decimal.py39
-rw-r--r--Lib/test/decimaltestdata/extra.decTest60
-rw-r--r--Lib/test/test_decimal.py47
-rw-r--r--Misc/NEWS5
4 files changed, 126 insertions, 25 deletions
diff --git a/Lib/decimal.py b/Lib/decimal.py
index e0c691b..82d3256 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -2806,6 +2806,8 @@ class Decimal(object):
value. Note that a total ordering is defined for all possible abstract
representations.
"""
+ other = _convert_other(other, raiseit=True)
+
# if one is negative and the other is positive, it's easy
if self._sign and not other._sign:
return _NegativeOne
@@ -2875,6 +2877,8 @@ class Decimal(object):
Like compare_total, but with operand's sign ignored and assumed to be 0.
"""
+ other = _convert_other(other, raiseit=True)
+
s = self.copy_abs()
o = other.copy_abs()
return s.compare_total(o)
@@ -3243,6 +3247,9 @@ class Decimal(object):
"""Applies an 'and' operation between self and other's digits."""
if context is None:
context = getcontext()
+
+ other = _convert_other(other, raiseit=True)
+
if not self._islogical() or not other._islogical():
return context._raise_error(InvalidOperation)
@@ -3264,6 +3271,9 @@ class Decimal(object):
"""Applies an 'or' operation between self and other's digits."""
if context is None:
context = getcontext()
+
+ other = _convert_other(other, raiseit=True)
+
if not self._islogical() or not other._islogical():
return context._raise_error(InvalidOperation)
@@ -3278,6 +3288,9 @@ class Decimal(object):
"""Applies an 'xor' operation between self and other's digits."""
if context is None:
context = getcontext()
+
+ other = _convert_other(other, raiseit=True)
+
if not self._islogical() or not other._islogical():
return context._raise_error(InvalidOperation)
@@ -3491,6 +3504,8 @@ class Decimal(object):
if context is None:
context = getcontext()
+ other = _convert_other(other, raiseit=True)
+
ans = self._check_nans(other, context)
if ans:
return ans
@@ -3507,19 +3522,23 @@ class Decimal(object):
torot = int(other)
rotdig = self._int
topad = context.prec - len(rotdig)
- if topad:
+ if topad > 0:
rotdig = '0'*topad + rotdig
+ elif topad < 0:
+ rotdig = rotdig[-topad:]
# let's rotate!
rotated = rotdig[torot:] + rotdig[:torot]
return _dec_from_triple(self._sign,
rotated.lstrip('0') or '0', self._exp)
- def scaleb (self, other, context=None):
+ def scaleb(self, other, context=None):
"""Returns self operand after adding the second value to its exp."""
if context is None:
context = getcontext()
+ other = _convert_other(other, raiseit=True)
+
ans = self._check_nans(other, context)
if ans:
return ans
@@ -3543,6 +3562,8 @@ class Decimal(object):
if context is None:
context = getcontext()
+ other = _convert_other(other, raiseit=True)
+
ans = self._check_nans(other, context)
if ans:
return ans
@@ -3557,22 +3578,22 @@ class Decimal(object):
# get values, pad if necessary
torot = int(other)
- if not torot:
- return Decimal(self)
rotdig = self._int
topad = context.prec - len(rotdig)
- if topad:
+ if topad > 0:
rotdig = '0'*topad + rotdig
+ elif topad < 0:
+ rotdig = rotdig[-topad:]
# let's shift!
if torot < 0:
- rotated = rotdig[:torot]
+ shifted = rotdig[:torot]
else:
- rotated = rotdig + '0'*torot
- rotated = rotated[-context.prec:]
+ shifted = rotdig + '0'*torot
+ shifted = shifted[-context.prec:]
return _dec_from_triple(self._sign,
- rotated.lstrip('0') or '0', self._exp)
+ shifted.lstrip('0') or '0', self._exp)
# Support for pickling, copy, and deepcopy
def __reduce__(self):
diff --git a/Lib/test/decimaltestdata/extra.decTest b/Lib/test/decimaltestdata/extra.decTest
index 15c1b52..2640842 100644
--- a/Lib/test/decimaltestdata/extra.decTest
+++ b/Lib/test/decimaltestdata/extra.decTest
@@ -154,22 +154,6 @@ extr1301 fma Inf 0 sNaN456 -> NaN Invalid_operation
extr1302 fma 0E123 -Inf sNaN789 -> NaN Invalid_operation
extr1302 fma -Inf 0E-456 sNaN148 -> NaN Invalid_operation
--- Issue #6794: when comparing NaNs using compare_total, payloads
--- should be compared as though positive integers; not
--- lexicographically as strings.
-extr1400 comparetotal NaN123 NaN45 -> 1
-extr1401 comparetotal sNaN123 sNaN45 -> 1
-extr1402 comparetotal -NaN123 -NaN45 -> -1
-extr1403 comparetotal -sNaN123 -sNaN45 -> -1
-extr1404 comparetotal NaN45 NaN123 -> -1
-extr1405 comparetotal sNaN45 sNaN123 -> -1
-extr1406 comparetotal -NaN45 -NaN123 -> 1
-extr1407 comparetotal -sNaN45 -sNaN123 -> 1
-
-extr1410 comparetotal -sNaN63450748854172416 -sNaN911993 -> -1
-extr1411 comparetotmag NaN1222222222222 -NaN999999 -> 1
-
-
-- max/min/max_mag/min_mag bug in 2.5.2/2.6/3.0: max(NaN, finite) gave
-- incorrect answers when the finite number required rounding; similarly
-- for the other thre functions
@@ -187,6 +171,50 @@ extr1421 max_mag NaN999999999 0.001234567 -> 0.00123457 Inexact Rounded
extr1430 min_mag 9181716151 -NaN -> 9.18172E+9 Inexact Rounded
extr1431 min_mag NaN4 1.818180E100 -> 1.81818E+100 Rounded
+-- Issue #6794: when comparing NaNs using compare_total, payloads
+-- should be compared as though positive integers; not
+-- lexicographically as strings.
+extr1500 comparetotal NaN123 NaN45 -> 1
+extr1501 comparetotal sNaN123 sNaN45 -> 1
+extr1502 comparetotal -NaN123 -NaN45 -> -1
+extr1503 comparetotal -sNaN123 -sNaN45 -> -1
+extr1504 comparetotal NaN45 NaN123 -> -1
+extr1505 comparetotal sNaN45 sNaN123 -> -1
+extr1506 comparetotal -NaN45 -NaN123 -> 1
+extr1507 comparetotal -sNaN45 -sNaN123 -> 1
+
+extr1510 comparetotal -sNaN63450748854172416 -sNaN911993 -> -1
+extr1511 comparetotmag NaN1222222222222 -NaN999999 -> 1
+
+-- Issue #7233: rotate and scale should truncate an argument
+-- of length greater than the current precision.
+precision: 4
+extr1600 rotate 1234567 -5 -> NaN Invalid_operation
+extr1601 rotate 1234567 -4 -> 4567
+extr1602 rotate 1234567 -3 -> 5674
+extr1603 rotate 1234567 -2 -> 6745
+extr1604 rotate 1234567 -1 -> 7456
+extr1605 rotate 1234567 0 -> 4567
+extr1606 rotate 1234567 1 -> 5674
+extr1607 rotate 1234567 2 -> 6745
+extr1608 rotate 1234567 3 -> 7456
+extr1609 rotate 1234567 4 -> 4567
+extr1610 rotate 1234567 5 -> NaN Invalid_operation
+
+extr1650 shift 1234567 -5 -> NaN Invalid_operation
+extr1651 shift 1234567 -4 -> 0
+extr1652 shift 1234567 -3 -> 4
+extr1653 shift 1234567 -2 -> 45
+extr1654 shift 1234567 -1 -> 456
+extr1655 shift 1234567 0 -> 4567
+extr1656 shift 1234567 1 -> 5670
+extr1657 shift 1234567 2 -> 6700
+extr1658 shift 1234567 3 -> 7000
+extr1659 shift 1234567 4 -> 0
+extr1660 shift 1234567 5 -> NaN Invalid_operation
+
+
+
-- Tests for the is_* boolean operations
precision: 9
maxExponent: 999
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index ac09e71..f556c79 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -1530,6 +1530,53 @@ class DecimalUsabilityTest(unittest.TestCase):
self.assertEqual(str(Decimal(0).sqrt()),
str(c.sqrt(Decimal(0))))
+ def test_conversions_from_int(self):
+ # Check that methods taking a second Decimal argument will
+ # always accept an integer in place of a Decimal.
+ self.assertEqual(Decimal(4).compare(3),
+ Decimal(4).compare(Decimal(3)))
+ self.assertEqual(Decimal(4).compare_signal(3),
+ Decimal(4).compare_signal(Decimal(3)))
+ self.assertEqual(Decimal(4).compare_total(3),
+ Decimal(4).compare_total(Decimal(3)))
+ self.assertEqual(Decimal(4).compare_total_mag(3),
+ Decimal(4).compare_total_mag(Decimal(3)))
+ self.assertEqual(Decimal(10101).logical_and(1001),
+ Decimal(10101).logical_and(Decimal(1001)))
+ self.assertEqual(Decimal(10101).logical_or(1001),
+ Decimal(10101).logical_or(Decimal(1001)))
+ self.assertEqual(Decimal(10101).logical_xor(1001),
+ Decimal(10101).logical_xor(Decimal(1001)))
+ self.assertEqual(Decimal(567).max(123),
+ Decimal(567).max(Decimal(123)))
+ self.assertEqual(Decimal(567).max_mag(123),
+ Decimal(567).max_mag(Decimal(123)))
+ self.assertEqual(Decimal(567).min(123),
+ Decimal(567).min(Decimal(123)))
+ self.assertEqual(Decimal(567).min_mag(123),
+ Decimal(567).min_mag(Decimal(123)))
+ self.assertEqual(Decimal(567).next_toward(123),
+ Decimal(567).next_toward(Decimal(123)))
+ self.assertEqual(Decimal(1234).quantize(100),
+ Decimal(1234).quantize(Decimal(100)))
+ self.assertEqual(Decimal(768).remainder_near(1234),
+ Decimal(768).remainder_near(Decimal(1234)))
+ self.assertEqual(Decimal(123).rotate(1),
+ Decimal(123).rotate(Decimal(1)))
+ self.assertEqual(Decimal(1234).same_quantum(1000),
+ Decimal(1234).same_quantum(Decimal(1000)))
+ self.assertEqual(Decimal('9.123').scaleb(-100),
+ Decimal('9.123').scaleb(Decimal(-100)))
+ self.assertEqual(Decimal(456).shift(-1),
+ Decimal(456).shift(Decimal(-1)))
+
+ self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
+ Decimal(-12).fma(Decimal(45), Decimal(67)))
+ self.assertEqual(Decimal(-12).fma(45, 67),
+ Decimal(-12).fma(Decimal(45), Decimal(67)))
+ self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
+ Decimal(-12).fma(Decimal(45), Decimal(67)))
+
class DecimalPythonAPItests(unittest.TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index a53b28c..e7384dc 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -120,6 +120,11 @@ C-API
Library
-------
+- Issue #7233: Fix a number of two-argument Decimal methods to make
+ sure that they accept an int or long as the second argument. Also
+ fix buggy handling of large arguments (those with coefficient longer
+ than the current precision) in shift and rotate.
+
- Issue #4750: Store the basename of the original filename in the gzip FNAME
header as required by RFC 1952.