mirror of
https://github.com/python/cpython.git
synced 2025-08-16 06:40:56 +00:00
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. ........
This commit is contained in:
parent
99eb961a56
commit
d8a2e2b794
4 changed files with 126 additions and 25 deletions
|
@ -2680,6 +2680,8 @@ class Decimal(object):
|
||||||
value. Note that a total ordering is defined for all possible abstract
|
value. Note that a total ordering is defined for all possible abstract
|
||||||
representations.
|
representations.
|
||||||
"""
|
"""
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
# if one is negative and the other is positive, it's easy
|
# if one is negative and the other is positive, it's easy
|
||||||
if self._sign and not other._sign:
|
if self._sign and not other._sign:
|
||||||
return _NegativeOne
|
return _NegativeOne
|
||||||
|
@ -2749,6 +2751,8 @@ class Decimal(object):
|
||||||
|
|
||||||
Like compare_total, but with operand's sign ignored and assumed to be 0.
|
Like compare_total, but with operand's sign ignored and assumed to be 0.
|
||||||
"""
|
"""
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
s = self.copy_abs()
|
s = self.copy_abs()
|
||||||
o = other.copy_abs()
|
o = other.copy_abs()
|
||||||
return s.compare_total(o)
|
return s.compare_total(o)
|
||||||
|
@ -3117,6 +3121,9 @@ class Decimal(object):
|
||||||
"""Applies an 'and' operation between self and other's digits."""
|
"""Applies an 'and' operation between self and other's digits."""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
if not self._islogical() or not other._islogical():
|
if not self._islogical() or not other._islogical():
|
||||||
return context._raise_error(InvalidOperation)
|
return context._raise_error(InvalidOperation)
|
||||||
|
|
||||||
|
@ -3138,6 +3145,9 @@ class Decimal(object):
|
||||||
"""Applies an 'or' operation between self and other's digits."""
|
"""Applies an 'or' operation between self and other's digits."""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
if not self._islogical() or not other._islogical():
|
if not self._islogical() or not other._islogical():
|
||||||
return context._raise_error(InvalidOperation)
|
return context._raise_error(InvalidOperation)
|
||||||
|
|
||||||
|
@ -3152,6 +3162,9 @@ class Decimal(object):
|
||||||
"""Applies an 'xor' operation between self and other's digits."""
|
"""Applies an 'xor' operation between self and other's digits."""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
if not self._islogical() or not other._islogical():
|
if not self._islogical() or not other._islogical():
|
||||||
return context._raise_error(InvalidOperation)
|
return context._raise_error(InvalidOperation)
|
||||||
|
|
||||||
|
@ -3365,6 +3378,8 @@ class Decimal(object):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
ans = self._check_nans(other, context)
|
ans = self._check_nans(other, context)
|
||||||
if ans:
|
if ans:
|
||||||
return ans
|
return ans
|
||||||
|
@ -3381,19 +3396,23 @@ class Decimal(object):
|
||||||
torot = int(other)
|
torot = int(other)
|
||||||
rotdig = self._int
|
rotdig = self._int
|
||||||
topad = context.prec - len(rotdig)
|
topad = context.prec - len(rotdig)
|
||||||
if topad:
|
if topad > 0:
|
||||||
rotdig = '0'*topad + rotdig
|
rotdig = '0'*topad + rotdig
|
||||||
|
elif topad < 0:
|
||||||
|
rotdig = rotdig[-topad:]
|
||||||
|
|
||||||
# let's rotate!
|
# let's rotate!
|
||||||
rotated = rotdig[torot:] + rotdig[:torot]
|
rotated = rotdig[torot:] + rotdig[:torot]
|
||||||
return _dec_from_triple(self._sign,
|
return _dec_from_triple(self._sign,
|
||||||
rotated.lstrip('0') or '0', self._exp)
|
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."""
|
"""Returns self operand after adding the second value to its exp."""
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
ans = self._check_nans(other, context)
|
ans = self._check_nans(other, context)
|
||||||
if ans:
|
if ans:
|
||||||
return ans
|
return ans
|
||||||
|
@ -3417,6 +3436,8 @@ class Decimal(object):
|
||||||
if context is None:
|
if context is None:
|
||||||
context = getcontext()
|
context = getcontext()
|
||||||
|
|
||||||
|
other = _convert_other(other, raiseit=True)
|
||||||
|
|
||||||
ans = self._check_nans(other, context)
|
ans = self._check_nans(other, context)
|
||||||
if ans:
|
if ans:
|
||||||
return ans
|
return ans
|
||||||
|
@ -3431,22 +3452,22 @@ class Decimal(object):
|
||||||
|
|
||||||
# get values, pad if necessary
|
# get values, pad if necessary
|
||||||
torot = int(other)
|
torot = int(other)
|
||||||
if not torot:
|
|
||||||
return Decimal(self)
|
|
||||||
rotdig = self._int
|
rotdig = self._int
|
||||||
topad = context.prec - len(rotdig)
|
topad = context.prec - len(rotdig)
|
||||||
if topad:
|
if topad > 0:
|
||||||
rotdig = '0'*topad + rotdig
|
rotdig = '0'*topad + rotdig
|
||||||
|
elif topad < 0:
|
||||||
|
rotdig = rotdig[-topad:]
|
||||||
|
|
||||||
# let's shift!
|
# let's shift!
|
||||||
if torot < 0:
|
if torot < 0:
|
||||||
rotated = rotdig[:torot]
|
shifted = rotdig[:torot]
|
||||||
else:
|
else:
|
||||||
rotated = rotdig + '0'*torot
|
shifted = rotdig + '0'*torot
|
||||||
rotated = rotated[-context.prec:]
|
shifted = shifted[-context.prec:]
|
||||||
|
|
||||||
return _dec_from_triple(self._sign,
|
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
|
# Support for pickling, copy, and deepcopy
|
||||||
def __reduce__(self):
|
def __reduce__(self):
|
||||||
|
|
|
@ -154,22 +154,6 @@ extr1301 fma Inf 0 sNaN456 -> NaN Invalid_operation
|
||||||
extr1302 fma 0E123 -Inf sNaN789 -> NaN Invalid_operation
|
extr1302 fma 0E123 -Inf sNaN789 -> NaN Invalid_operation
|
||||||
extr1302 fma -Inf 0E-456 sNaN148 -> 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
|
-- 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
|
-- incorrect answers when the finite number required rounding; similarly
|
||||||
-- for the other thre functions
|
-- 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
|
extr1430 min_mag 9181716151 -NaN -> 9.18172E+9 Inexact Rounded
|
||||||
extr1431 min_mag NaN4 1.818180E100 -> 1.81818E+100 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
|
-- Tests for the is_* boolean operations
|
||||||
precision: 9
|
precision: 9
|
||||||
maxExponent: 999
|
maxExponent: 999
|
||||||
|
|
|
@ -1358,6 +1358,53 @@ class DecimalUsabilityTest(unittest.TestCase):
|
||||||
self.assertEqual(str(Decimal(0).sqrt()),
|
self.assertEqual(str(Decimal(0).sqrt()),
|
||||||
str(c.sqrt(Decimal(0))))
|
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):
|
class DecimalPythonAPItests(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@ Core and Builtins
|
||||||
Library
|
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 #7082: When falling back to the MIME 'name' parameter, the
|
- Issue #7082: When falling back to the MIME 'name' parameter, the
|
||||||
correct place to look for it is the Content-Type header.
|
correct place to look for it is the Content-Type header.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue