Converts a float to a decimal number, exactly. Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). Since 0.1 is not exactly representable in binary floating point, the value is stored as the nearest representable value which is 0x1.999999999999a
(cls, f)
| 681 | |
| 682 | @classmethod |
| 683 | def from_float(cls, f): |
| 684 | """Converts a float to a decimal number, exactly. |
| 685 | |
| 686 | Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). |
| 687 | Since 0.1 is not exactly representable in binary floating point, the |
| 688 | value is stored as the nearest representable value which is |
| 689 | 0x1.999999999999ap-4. The exact equivalent of the value in decimal |
| 690 | is 0.1000000000000000055511151231257827021181583404541015625. |
| 691 | |
| 692 | >>> Decimal.from_float(0.1) |
| 693 | Decimal('0.1000000000000000055511151231257827021181583404541015625') |
| 694 | >>> Decimal.from_float(float('nan')) |
| 695 | Decimal('NaN') |
| 696 | >>> Decimal.from_float(float('inf')) |
| 697 | Decimal('Infinity') |
| 698 | >>> Decimal.from_float(-float('inf')) |
| 699 | Decimal('-Infinity') |
| 700 | >>> Decimal.from_float(-0.0) |
| 701 | Decimal('-0') |
| 702 | |
| 703 | """ |
| 704 | if isinstance(f, int): # handle integer inputs |
| 705 | sign = 0 if f >= 0 else 1 |
| 706 | k = 0 |
| 707 | coeff = str(abs(f)) |
| 708 | elif isinstance(f, float): |
| 709 | if _math.isinf(f) or _math.isnan(f): |
| 710 | return cls(repr(f)) |
| 711 | if _math.copysign(1.0, f) == 1.0: |
| 712 | sign = 0 |
| 713 | else: |
| 714 | sign = 1 |
| 715 | n, d = abs(f).as_integer_ratio() |
| 716 | k = d.bit_length() - 1 |
| 717 | coeff = str(n*5**k) |
| 718 | else: |
| 719 | raise TypeError("argument must be int or float.") |
| 720 | |
| 721 | result = _dec_from_triple(sign, coeff, -k) |
| 722 | if cls is Decimal: |
| 723 | return result |
| 724 | else: |
| 725 | return cls(result) |
| 726 | |
| 727 | def _isnan(self): |
| 728 | """Returns whether the number is not actually one. |
no test coverage detected