Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9050bb2

Browse files
committed
Merged revisions 75947 via svnmerge from
svn+ssh://[email protected]/python/branches/py3k ................ r75947 | mark.dickinson | 2009-10-29 12:23:02 +0000 (Thu, 29 Oct 2009) | 20 lines Merged revisions 75943-75945 via svnmerge from svn+ssh://[email protected]/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. ........ ................
1 parent 00de1bd commit 9050bb2

4 files changed

Lines changed: 126 additions & 25 deletions

File tree

Lib/decimal.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,6 +2806,8 @@ def compare_total(self, other):
28062806
value. Note that a total ordering is defined for all possible abstract
28072807
representations.
28082808
"""
2809+
other = _convert_other(other, raiseit=True)
2810+
28092811
# if one is negative and the other is positive, it's easy
28102812
if self._sign and not other._sign:
28112813
return _NegativeOne
@@ -2875,6 +2877,8 @@ def compare_total_mag(self, other):
28752877
28762878
Like compare_total, but with operand's sign ignored and assumed to be 0.
28772879
"""
2880+
other = _convert_other(other, raiseit=True)
2881+
28782882
s = self.copy_abs()
28792883
o = other.copy_abs()
28802884
return s.compare_total(o)
@@ -3243,6 +3247,9 @@ def logical_and(self, other, context=None):
32433247
"""Applies an 'and' operation between self and other's digits."""
32443248
if context is None:
32453249
context = getcontext()
3250+
3251+
other = _convert_other(other, raiseit=True)
3252+
32463253
if not self._islogical() or not other._islogical():
32473254
return context._raise_error(InvalidOperation)
32483255

@@ -3264,6 +3271,9 @@ def logical_or(self, other, context=None):
32643271
"""Applies an 'or' operation between self and other's digits."""
32653272
if context is None:
32663273
context = getcontext()
3274+
3275+
other = _convert_other(other, raiseit=True)
3276+
32673277
if not self._islogical() or not other._islogical():
32683278
return context._raise_error(InvalidOperation)
32693279

@@ -3278,6 +3288,9 @@ def logical_xor(self, other, context=None):
32783288
"""Applies an 'xor' operation between self and other's digits."""
32793289
if context is None:
32803290
context = getcontext()
3291+
3292+
other = _convert_other(other, raiseit=True)
3293+
32813294
if not self._islogical() or not other._islogical():
32823295
return context._raise_error(InvalidOperation)
32833296

@@ -3491,6 +3504,8 @@ def rotate(self, other, context=None):
34913504
if context is None:
34923505
context = getcontext()
34933506

3507+
other = _convert_other(other, raiseit=True)
3508+
34943509
ans = self._check_nans(other, context)
34953510
if ans:
34963511
return ans
@@ -3507,19 +3522,23 @@ def rotate(self, other, context=None):
35073522
torot = int(other)
35083523
rotdig = self._int
35093524
topad = context.prec - len(rotdig)
3510-
if topad:
3525+
if topad > 0:
35113526
rotdig = '0'*topad + rotdig
3527+
elif topad < 0:
3528+
rotdig = rotdig[-topad:]
35123529

35133530
# let's rotate!
35143531
rotated = rotdig[torot:] + rotdig[:torot]
35153532
return _dec_from_triple(self._sign,
35163533
rotated.lstrip('0') or '0', self._exp)
35173534

3518-
def scaleb (self, other, context=None):
3535+
def scaleb(self, other, context=None):
35193536
"""Returns self operand after adding the second value to its exp."""
35203537
if context is None:
35213538
context = getcontext()
35223539

3540+
other = _convert_other(other, raiseit=True)
3541+
35233542
ans = self._check_nans(other, context)
35243543
if ans:
35253544
return ans
@@ -3543,6 +3562,8 @@ def shift(self, other, context=None):
35433562
if context is None:
35443563
context = getcontext()
35453564

3565+
other = _convert_other(other, raiseit=True)
3566+
35463567
ans = self._check_nans(other, context)
35473568
if ans:
35483569
return ans
@@ -3557,22 +3578,22 @@ def shift(self, other, context=None):
35573578

35583579
# get values, pad if necessary
35593580
torot = int(other)
3560-
if not torot:
3561-
return Decimal(self)
35623581
rotdig = self._int
35633582
topad = context.prec - len(rotdig)
3564-
if topad:
3583+
if topad > 0:
35653584
rotdig = '0'*topad + rotdig
3585+
elif topad < 0:
3586+
rotdig = rotdig[-topad:]
35663587

35673588
# let's shift!
35683589
if torot < 0:
3569-
rotated = rotdig[:torot]
3590+
shifted = rotdig[:torot]
35703591
else:
3571-
rotated = rotdig + '0'*torot
3572-
rotated = rotated[-context.prec:]
3592+
shifted = rotdig + '0'*torot
3593+
shifted = shifted[-context.prec:]
35733594

35743595
return _dec_from_triple(self._sign,
3575-
rotated.lstrip('0') or '0', self._exp)
3596+
shifted.lstrip('0') or '0', self._exp)
35763597

35773598
# Support for pickling, copy, and deepcopy
35783599
def __reduce__(self):

Lib/test/decimaltestdata/extra.decTest

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -154,22 +154,6 @@ extr1301 fma Inf 0 sNaN456 -> NaN Invalid_operation
154154
extr1302 fma 0E123 -Inf sNaN789 -> NaN Invalid_operation
155155
extr1302 fma -Inf 0E-456 sNaN148 -> NaN Invalid_operation
156156

157-
-- Issue #6794: when comparing NaNs using compare_total, payloads
158-
-- should be compared as though positive integers; not
159-
-- lexicographically as strings.
160-
extr1400 comparetotal NaN123 NaN45 -> 1
161-
extr1401 comparetotal sNaN123 sNaN45 -> 1
162-
extr1402 comparetotal -NaN123 -NaN45 -> -1
163-
extr1403 comparetotal -sNaN123 -sNaN45 -> -1
164-
extr1404 comparetotal NaN45 NaN123 -> -1
165-
extr1405 comparetotal sNaN45 sNaN123 -> -1
166-
extr1406 comparetotal -NaN45 -NaN123 -> 1
167-
extr1407 comparetotal -sNaN45 -sNaN123 -> 1
168-
169-
extr1410 comparetotal -sNaN63450748854172416 -sNaN911993 -> -1
170-
extr1411 comparetotmag NaN1222222222222 -NaN999999 -> 1
171-
172-
173157
-- max/min/max_mag/min_mag bug in 2.5.2/2.6/3.0: max(NaN, finite) gave
174158
-- incorrect answers when the finite number required rounding; similarly
175159
-- for the other thre functions
@@ -187,6 +171,50 @@ extr1421 max_mag NaN999999999 0.001234567 -> 0.00123457 Inexact Rounded
187171
extr1430 min_mag 9181716151 -NaN -> 9.18172E+9 Inexact Rounded
188172
extr1431 min_mag NaN4 1.818180E100 -> 1.81818E+100 Rounded
189173

174+
-- Issue #6794: when comparing NaNs using compare_total, payloads
175+
-- should be compared as though positive integers; not
176+
-- lexicographically as strings.
177+
extr1500 comparetotal NaN123 NaN45 -> 1
178+
extr1501 comparetotal sNaN123 sNaN45 -> 1
179+
extr1502 comparetotal -NaN123 -NaN45 -> -1
180+
extr1503 comparetotal -sNaN123 -sNaN45 -> -1
181+
extr1504 comparetotal NaN45 NaN123 -> -1
182+
extr1505 comparetotal sNaN45 sNaN123 -> -1
183+
extr1506 comparetotal -NaN45 -NaN123 -> 1
184+
extr1507 comparetotal -sNaN45 -sNaN123 -> 1
185+
186+
extr1510 comparetotal -sNaN63450748854172416 -sNaN911993 -> -1
187+
extr1511 comparetotmag NaN1222222222222 -NaN999999 -> 1
188+
189+
-- Issue #7233: rotate and scale should truncate an argument
190+
-- of length greater than the current precision.
191+
precision: 4
192+
extr1600 rotate 1234567 -5 -> NaN Invalid_operation
193+
extr1601 rotate 1234567 -4 -> 4567
194+
extr1602 rotate 1234567 -3 -> 5674
195+
extr1603 rotate 1234567 -2 -> 6745
196+
extr1604 rotate 1234567 -1 -> 7456
197+
extr1605 rotate 1234567 0 -> 4567
198+
extr1606 rotate 1234567 1 -> 5674
199+
extr1607 rotate 1234567 2 -> 6745
200+
extr1608 rotate 1234567 3 -> 7456
201+
extr1609 rotate 1234567 4 -> 4567
202+
extr1610 rotate 1234567 5 -> NaN Invalid_operation
203+
204+
extr1650 shift 1234567 -5 -> NaN Invalid_operation
205+
extr1651 shift 1234567 -4 -> 0
206+
extr1652 shift 1234567 -3 -> 4
207+
extr1653 shift 1234567 -2 -> 45
208+
extr1654 shift 1234567 -1 -> 456
209+
extr1655 shift 1234567 0 -> 4567
210+
extr1656 shift 1234567 1 -> 5670
211+
extr1657 shift 1234567 2 -> 6700
212+
extr1658 shift 1234567 3 -> 7000
213+
extr1659 shift 1234567 4 -> 0
214+
extr1660 shift 1234567 5 -> NaN Invalid_operation
215+
216+
217+
190218
-- Tests for the is_* boolean operations
191219
precision: 9
192220
maxExponent: 999

Lib/test/test_decimal.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,53 @@ def test_implicit_context(self):
15291529
self.assertEqual(str(Decimal(0).sqrt()),
15301530
str(c.sqrt(Decimal(0))))
15311531

1532+
def test_conversions_from_int(self):
1533+
# Check that methods taking a second Decimal argument will
1534+
# always accept an integer in place of a Decimal.
1535+
self.assertEqual(Decimal(4).compare(3),
1536+
Decimal(4).compare(Decimal(3)))
1537+
self.assertEqual(Decimal(4).compare_signal(3),
1538+
Decimal(4).compare_signal(Decimal(3)))
1539+
self.assertEqual(Decimal(4).compare_total(3),
1540+
Decimal(4).compare_total(Decimal(3)))
1541+
self.assertEqual(Decimal(4).compare_total_mag(3),
1542+
Decimal(4).compare_total_mag(Decimal(3)))
1543+
self.assertEqual(Decimal(10101).logical_and(1001),
1544+
Decimal(10101).logical_and(Decimal(1001)))
1545+
self.assertEqual(Decimal(10101).logical_or(1001),
1546+
Decimal(10101).logical_or(Decimal(1001)))
1547+
self.assertEqual(Decimal(10101).logical_xor(1001),
1548+
Decimal(10101).logical_xor(Decimal(1001)))
1549+
self.assertEqual(Decimal(567).max(123),
1550+
Decimal(567).max(Decimal(123)))
1551+
self.assertEqual(Decimal(567).max_mag(123),
1552+
Decimal(567).max_mag(Decimal(123)))
1553+
self.assertEqual(Decimal(567).min(123),
1554+
Decimal(567).min(Decimal(123)))
1555+
self.assertEqual(Decimal(567).min_mag(123),
1556+
Decimal(567).min_mag(Decimal(123)))
1557+
self.assertEqual(Decimal(567).next_toward(123),
1558+
Decimal(567).next_toward(Decimal(123)))
1559+
self.assertEqual(Decimal(1234).quantize(100),
1560+
Decimal(1234).quantize(Decimal(100)))
1561+
self.assertEqual(Decimal(768).remainder_near(1234),
1562+
Decimal(768).remainder_near(Decimal(1234)))
1563+
self.assertEqual(Decimal(123).rotate(1),
1564+
Decimal(123).rotate(Decimal(1)))
1565+
self.assertEqual(Decimal(1234).same_quantum(1000),
1566+
Decimal(1234).same_quantum(Decimal(1000)))
1567+
self.assertEqual(Decimal('9.123').scaleb(-100),
1568+
Decimal('9.123').scaleb(Decimal(-100)))
1569+
self.assertEqual(Decimal(456).shift(-1),
1570+
Decimal(456).shift(Decimal(-1)))
1571+
1572+
self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
1573+
Decimal(-12).fma(Decimal(45), Decimal(67)))
1574+
self.assertEqual(Decimal(-12).fma(45, 67),
1575+
Decimal(-12).fma(Decimal(45), Decimal(67)))
1576+
self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
1577+
Decimal(-12).fma(Decimal(45), Decimal(67)))
1578+
15321579

15331580
class DecimalPythonAPItests(unittest.TestCase):
15341581

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ Core and Builtins
3737
Library
3838
-------
3939

40+
- Issue #7233: Fix a number of two-argument Decimal methods to make
41+
sure that they accept an int or long as the second argument. Also
42+
fix buggy handling of large arguments (those with coefficient longer
43+
than the current precision) in shift and rotate.
44+
4045
- Issue #7205: Fix a possible deadlock when using a BZ2File object from
4146
several threads at once.
4247

0 commit comments

Comments
 (0)