norae / docker /deezer-spleeter-env /lib64 /python3.10 /site-packages /future /builtins /newround.py
| """ | |
| ``python-future``: pure Python implementation of Python 3 round(). | |
| """ | |
| from __future__ import division | |
| from future.utils import PYPY, PY26, bind_method | |
| # Use the decimal module for simplicity of implementation (and | |
| # hopefully correctness). | |
| from decimal import Decimal, ROUND_HALF_EVEN | |
| def newround(number, ndigits=None): | |
| """ | |
| See Python 3 documentation: uses Banker's Rounding. | |
| Delegates to the __round__ method if for some reason this exists. | |
| If not, rounds a number to a given precision in decimal digits (default | |
| 0 digits). This returns an int when called with one argument, | |
| otherwise the same type as the number. ndigits may be negative. | |
| See the test_round method in future/tests/test_builtins.py for | |
| examples. | |
| """ | |
| return_int = False | |
| if ndigits is None: | |
| return_int = True | |
| ndigits = 0 | |
| if hasattr(number, '__round__'): | |
| return number.__round__(ndigits) | |
| exponent = Decimal('10') ** (-ndigits) | |
| # Work around issue #24: round() breaks on PyPy with NumPy's types | |
| # Also breaks on CPython with NumPy's specialized int types like uint64 | |
| if 'numpy' in repr(type(number)): | |
| number = float(number) | |
| if isinstance(number, Decimal): | |
| d = number | |
| else: | |
| if not PY26: | |
| d = Decimal.from_float(number) | |
| else: | |
| d = from_float_26(number) | |
| if ndigits < 0: | |
| result = newround(d / exponent) * exponent | |
| else: | |
| result = d.quantize(exponent, rounding=ROUND_HALF_EVEN) | |
| if return_int: | |
| return int(result) | |
| else: | |
| return float(result) | |
| ### From Python 2.7's decimal.py. Only needed to support Py2.6: | |
| def from_float_26(f): | |
| """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.999999999999ap-4. The exact equivalent of the value in decimal | |
| is 0.1000000000000000055511151231257827021181583404541015625. | |
| >>> Decimal.from_float(0.1) | |
| Decimal('0.1000000000000000055511151231257827021181583404541015625') | |
| >>> Decimal.from_float(float('nan')) | |
| Decimal('NaN') | |
| >>> Decimal.from_float(float('inf')) | |
| Decimal('Infinity') | |
| >>> Decimal.from_float(-float('inf')) | |
| Decimal('-Infinity') | |
| >>> Decimal.from_float(-0.0) | |
| Decimal('-0') | |
| """ | |
| import math as _math | |
| from decimal import _dec_from_triple # only available on Py2.6 and Py2.7 (not 3.3) | |
| if isinstance(f, (int, long)): # handle integer inputs | |
| return Decimal(f) | |
| if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float | |
| return Decimal(repr(f)) | |
| if _math.copysign(1.0, f) == 1.0: | |
| sign = 0 | |
| else: | |
| sign = 1 | |
| n, d = abs(f).as_integer_ratio() | |
| # int.bit_length() method doesn't exist on Py2.6: | |
| def bit_length(d): | |
| if d != 0: | |
| return len(bin(abs(d))) - 2 | |
| else: | |
| return 0 | |
| k = bit_length(d) - 1 | |
| result = _dec_from_triple(sign, str(n*5**k), -k) | |
| return result | |
| __all__ = ['newround'] | |