Mercurial > repos > shellac > guppy_basecaller
comparison env/lib/python3.7/site-packages/future/builtins/newround.py @ 2:6af9afd405e9 draft
"planemo upload commit 0a63dd5f4d38a1f6944587f52a8cd79874177fc1"
| author | shellac |
|---|---|
| date | Thu, 14 May 2020 14:56:58 -0400 |
| parents | 26e78fe6e8c4 |
| children |
comparison
equal
deleted
inserted
replaced
| 1:75ca89e9b81c | 2:6af9afd405e9 |
|---|---|
| 1 """ | |
| 2 ``python-future``: pure Python implementation of Python 3 round(). | |
| 3 """ | |
| 4 | |
| 5 from future.utils import PYPY, PY26, bind_method | |
| 6 | |
| 7 # Use the decimal module for simplicity of implementation (and | |
| 8 # hopefully correctness). | |
| 9 from decimal import Decimal, ROUND_HALF_EVEN | |
| 10 | |
| 11 | |
| 12 def newround(number, ndigits=None): | |
| 13 """ | |
| 14 See Python 3 documentation: uses Banker's Rounding. | |
| 15 | |
| 16 Delegates to the __round__ method if for some reason this exists. | |
| 17 | |
| 18 If not, rounds a number to a given precision in decimal digits (default | |
| 19 0 digits). This returns an int when called with one argument, | |
| 20 otherwise the same type as the number. ndigits may be negative. | |
| 21 | |
| 22 See the test_round method in future/tests/test_builtins.py for | |
| 23 examples. | |
| 24 """ | |
| 25 return_int = False | |
| 26 if ndigits is None: | |
| 27 return_int = True | |
| 28 ndigits = 0 | |
| 29 if hasattr(number, '__round__'): | |
| 30 return number.__round__(ndigits) | |
| 31 | |
| 32 if ndigits < 0: | |
| 33 raise NotImplementedError('negative ndigits not supported yet') | |
| 34 exponent = Decimal('10') ** (-ndigits) | |
| 35 | |
| 36 if PYPY: | |
| 37 # Work around issue #24: round() breaks on PyPy with NumPy's types | |
| 38 if 'numpy' in repr(type(number)): | |
| 39 number = float(number) | |
| 40 | |
| 41 if isinstance(number, Decimal): | |
| 42 d = number | |
| 43 else: | |
| 44 if not PY26: | |
| 45 d = Decimal.from_float(number).quantize(exponent, | |
| 46 rounding=ROUND_HALF_EVEN) | |
| 47 else: | |
| 48 d = from_float_26(number).quantize(exponent, rounding=ROUND_HALF_EVEN) | |
| 49 | |
| 50 if return_int: | |
| 51 return int(d) | |
| 52 else: | |
| 53 return float(d) | |
| 54 | |
| 55 | |
| 56 ### From Python 2.7's decimal.py. Only needed to support Py2.6: | |
| 57 | |
| 58 def from_float_26(f): | |
| 59 """Converts a float to a decimal number, exactly. | |
| 60 | |
| 61 Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). | |
| 62 Since 0.1 is not exactly representable in binary floating point, the | |
| 63 value is stored as the nearest representable value which is | |
| 64 0x1.999999999999ap-4. The exact equivalent of the value in decimal | |
| 65 is 0.1000000000000000055511151231257827021181583404541015625. | |
| 66 | |
| 67 >>> Decimal.from_float(0.1) | |
| 68 Decimal('0.1000000000000000055511151231257827021181583404541015625') | |
| 69 >>> Decimal.from_float(float('nan')) | |
| 70 Decimal('NaN') | |
| 71 >>> Decimal.from_float(float('inf')) | |
| 72 Decimal('Infinity') | |
| 73 >>> Decimal.from_float(-float('inf')) | |
| 74 Decimal('-Infinity') | |
| 75 >>> Decimal.from_float(-0.0) | |
| 76 Decimal('-0') | |
| 77 | |
| 78 """ | |
| 79 import math as _math | |
| 80 from decimal import _dec_from_triple # only available on Py2.6 and Py2.7 (not 3.3) | |
| 81 | |
| 82 if isinstance(f, (int, long)): # handle integer inputs | |
| 83 return Decimal(f) | |
| 84 if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float | |
| 85 return Decimal(repr(f)) | |
| 86 if _math.copysign(1.0, f) == 1.0: | |
| 87 sign = 0 | |
| 88 else: | |
| 89 sign = 1 | |
| 90 n, d = abs(f).as_integer_ratio() | |
| 91 # int.bit_length() method doesn't exist on Py2.6: | |
| 92 def bit_length(d): | |
| 93 if d != 0: | |
| 94 return len(bin(abs(d))) - 2 | |
| 95 else: | |
| 96 return 0 | |
| 97 k = bit_length(d) - 1 | |
| 98 result = _dec_from_triple(sign, str(n*5**k), -k) | |
| 99 return result | |
| 100 | |
| 101 | |
| 102 __all__ = ['newround'] |
