Skip to content

Commit 6d1dece

Browse files
andrewnestermdickinson
authored andcommitted
Fixed #29534 - _decimal difference with _pydecimal (#65)
1 parent c33ee85 commit 6d1dece

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

Lib/_pydecimal.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -734,18 +734,23 @@ def from_float(cls, f):
734734
735735
"""
736736
if isinstance(f, int): # handle integer inputs
737-
return cls(f)
738-
if not isinstance(f, float):
739-
raise TypeError("argument must be int or float.")
740-
if _math.isinf(f) or _math.isnan(f):
741-
return cls(repr(f))
742-
if _math.copysign(1.0, f) == 1.0:
743-
sign = 0
737+
sign = 0 if f >= 0 else 1
738+
k = 0
739+
coeff = str(abs(f))
740+
elif isinstance(f, float):
741+
if _math.isinf(f) or _math.isnan(f):
742+
return cls(repr(f))
743+
if _math.copysign(1.0, f) == 1.0:
744+
sign = 0
745+
else:
746+
sign = 1
747+
n, d = abs(f).as_integer_ratio()
748+
k = d.bit_length() - 1
749+
coeff = str(n*5**k)
744750
else:
745-
sign = 1
746-
n, d = abs(f).as_integer_ratio()
747-
k = d.bit_length() - 1
748-
result = _dec_from_triple(sign, str(n*5**k), -k)
751+
raise TypeError("argument must be int or float.")
752+
753+
result = _dec_from_triple(sign, coeff, -k)
749754
if cls is Decimal:
750755
return result
751756
else:

Lib/test/test_decimal.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,16 @@ def test_wide_char_separator_decimal_point(self):
11851185
self.assertEqual(format(Decimal('100000000.123'), 'n'),
11861186
'100\u066c000\u066c000\u066b123')
11871187

1188+
def test_decimal_from_float_argument_type(self):
1189+
class A(self.decimal.Decimal):
1190+
def __init__(self, a):
1191+
self.a_type = type(a)
1192+
a = A.from_float(42.5)
1193+
self.assertEqual(self.decimal.Decimal, a.a_type)
1194+
1195+
a = A.from_float(42)
1196+
self.assertEqual(self.decimal.Decimal, a.a_type)
1197+
11881198
class CFormatTest(FormatTest):
11891199
decimal = C
11901200
class PyFormatTest(FormatTest):

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- bpo-29534: Fixed different behaviour of Decimal.from_float() for _decimal and _pydecimal.
14+
1315
- bpo-29438: Fixed use-after-free problem in key sharing dict.
1416

1517
- Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0].

0 commit comments

Comments
 (0)