Skip to content

Commit eeb719e

Browse files
authored
Merge pull request RustPython#5411 from crazymerlyn/decimal-from-float
Fix inconsistent behavior of Decimal.from_float
2 parents 8cff0ed + 5f75728 commit eeb719e

File tree

2 files changed

+16
-13
lines changed

2 files changed

+16
-13
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: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,8 +1257,6 @@ def test_wide_char_separator_decimal_point(self):
12571257
self.assertEqual(format(Decimal('100000000.123'), 'n'),
12581258
'100\u066c000\u066c000\u066b123')
12591259

1260-
# TODO: RUSTPYTHON
1261-
@unittest.expectedFailure
12621260
def test_decimal_from_float_argument_type(self):
12631261
class A(self.decimal.Decimal):
12641262
def __init__(self, a):

0 commit comments

Comments
 (0)