"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "mpmath/libmp/libmpf.py" between
mpmath-1.0.0.tar.gz and mpmath-1.1.0.tar.gz

About: mpmath is a Python library for arbitrary-precision floating-point arithmetic.

libmpf.py  (mpmath-1.0.0):libmpf.py  (mpmath-1.1.0)
skipping to change at line 427 skipping to change at line 427
try: try:
m, e = math.frexp(x) m, e = math.frexp(x)
except: except:
if x == math_float_inf: return finf if x == math_float_inf: return finf
if x == -math_float_inf: return fninf if x == -math_float_inf: return fninf
return fnan return fnan
if x == math_float_inf: return finf if x == math_float_inf: return finf
if x == -math_float_inf: return fninf if x == -math_float_inf: return fninf
return from_man_exp(int(m*(1<<53)), e-53, prec, rnd) return from_man_exp(int(m*(1<<53)), e-53, prec, rnd)
def from_npfloat(x, prec=113, rnd=round_fast):
"""Create a raw mpf from a numpy float, rounding if necessary.
If prec >= 113, the result is guaranteed to represent exactly the
same number as the input. If prec is not specified, use prec=113."""
y = float(x)
if x == y: # ldexp overflows for float16
return from_float(y, prec, rnd)
import numpy as np
if np.isfinite(x):
m, e = np.frexp(x)
return from_man_exp(int(np.ldexp(m, 113)), int(e-113), prec, rnd)
if np.isposinf(x): return finf
if np.isneginf(x): return fninf
return fnan
def from_Decimal(x, prec=None, rnd=round_fast):
"""Create a raw mpf from a Decimal, rounding if necessary.
If prec is not specified, use the equivalent bit precision
of the number of significant digits in x."""
if x.is_nan(): return fnan
if x.is_infinite(): return fninf if x.is_signed() else finf
if prec is None:
prec = int(len(x.as_tuple()[1])*3.3219280948873626)
return from_str(str(x), prec, rnd)
def to_float(s, strict=False, rnd=round_fast): def to_float(s, strict=False, rnd=round_fast):
""" """
Convert a raw mpf to a Python float. The result is exact if the Convert a raw mpf to a Python float. The result is exact if the
bitcount of s is <= 53 and no underflow/overflow occurs. bitcount of s is <= 53 and no underflow/overflow occurs.
If the number is too large or too small to represent as a regular If the number is too large or too small to represent as a regular
float, it will be converted to inf or 0.0. Setting strict=True float, it will be converted to inf or 0.0. Setting strict=True
forces an OverflowError to be raised instead. forces an OverflowError to be raised instead.
Warning: with a directed rounding mode, the correct nearest representable Warning: with a directed rounding mode, the correct nearest representable
skipping to change at line 1221 skipping to change at line 1246
sign, digits, exponent = to_digits_exp(s, dps+3) sign, digits, exponent = to_digits_exp(s, dps+3)
# No digits: show only .0; round exponent to nearest # No digits: show only .0; round exponent to nearest
if not dps: if not dps:
if digits[0] in '56789': if digits[0] in '56789':
exponent += 1 exponent += 1
digits = ".0" digits = ".0"
else: else:
# Rounding up kills some instances of "...99999" # Rounding up kills some instances of "...99999"
if len(digits) > dps and digits[dps] in '56789' and \ if len(digits) > dps and digits[dps] in '56789':
(dps < 500 or digits[dps-4:dps] == '9999'): digits = digits[:dps]
digits2 = str(int(digits[:dps]) + 1) i = dps - 1
if len(digits2) > dps: while i >= 0 and digits[i] == '9':
digits2 = digits2[:dps] i -= 1
if i >= 0:
digits = digits[:i] + str(int(digits[i]) + 1) + '0' * (dps - i -
1)
else:
digits = '1' + '0' * (dps - 1)
exponent += 1 exponent += 1
digits = digits2
else: else:
digits = digits[:dps] digits = digits[:dps]
# Prettify numbers close to unit magnitude # Prettify numbers close to unit magnitude
if min_fixed < exponent < max_fixed: if min_fixed < exponent < max_fixed:
if exponent < 0: if exponent < 0:
digits = ("0"*int(-exponent)) + digits digits = ("0"*int(-exponent)) + digits
split = 1 split = 1
else: else:
split = exponent + 1 split = exponent + 1
skipping to change at line 1258 skipping to change at line 1286
digits = digits.rstrip('0') digits = digits.rstrip('0')
if digits[-1] == ".": if digits[-1] == ".":
digits += "0" digits += "0"
if exponent == 0 and dps and not show_zero_exponent: return sign + digits if exponent == 0 and dps and not show_zero_exponent: return sign + digits
if exponent >= 0: return sign + digits + "e+" + str(exponent) if exponent >= 0: return sign + digits + "e+" + str(exponent)
if exponent < 0: return sign + digits + "e" + str(exponent) if exponent < 0: return sign + digits + "e" + str(exponent)
def str_to_man_exp(x, base=10): def str_to_man_exp(x, base=10):
"""Helper function for from_str.""" """Helper function for from_str."""
x = x.lower().rstrip('l')
# Verify that the input is a valid float literal # Verify that the input is a valid float literal
float(x) float(x)
# Split into mantissa, exponent # Split into mantissa, exponent
x = x.lower()
parts = x.split('e') parts = x.split('e')
if len(parts) == 1: if len(parts) == 1:
exp = 0 exp = 0
else: # == 2 else: # == 2
x = parts[0] x = parts[0]
exp = int(parts[1]) exp = int(parts[1])
# Look for radix point in mantissa # Look for radix point in mantissa
parts = x.split('.') parts = x.split('.')
if len(parts) == 2: if len(parts) == 2:
a, b = parts[0], parts[1].rstrip('0') a, b = parts[0], parts[1].rstrip('0')
skipping to change at line 1288 skipping to change at line 1316
def from_str(x, prec, rnd=round_fast): def from_str(x, prec, rnd=round_fast):
"""Create a raw mpf from a decimal literal, rounding in the """Create a raw mpf from a decimal literal, rounding in the
specified direction if the input number cannot be represented specified direction if the input number cannot be represented
exactly as a binary floating-point number with the given number of exactly as a binary floating-point number with the given number of
bits. The literal syntax accepted is the same as for Python bits. The literal syntax accepted is the same as for Python
floats. floats.
TODO: the rounding does not work properly for large exponents. TODO: the rounding does not work properly for large exponents.
""" """
x = x.strip() x = x.lower().strip()
if x in special_str: if x in special_str:
return special_str[x] return special_str[x]
if '/' in x: if '/' in x:
p, q = x.split('/') p, q = x.split('/')
p, q = p.rstrip('l'), q.rstrip('l')
return from_rational(int(p), int(q), prec, rnd) return from_rational(int(p), int(q), prec, rnd)
man, exp = str_to_man_exp(x, base=10) man, exp = str_to_man_exp(x, base=10)
# XXX: appropriate cutoffs & track direction # XXX: appropriate cutoffs & track direction
# note no factors of 5 # note no factors of 5
if abs(exp) > 400: if abs(exp) > 400:
s = from_int(man, prec+10) s = from_int(man, prec+10)
s = mpf_mul(s, mpf_pow_int(ften, exp, prec+10), prec, rnd) s = mpf_mul(s, mpf_pow_int(ften, exp, prec+10), prec, rnd)
else: else:
 End of changes. 7 change blocks. 
8 lines changed or deleted 38 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)