def to_digits_exp(s, dps): """Helper function for representing the floating-point number s as a decimal with dps digits. Returns (sign, string, exponent) where sign is '' or '-', string is the digit string, and exponent is the decimal exponent as an int. If inexact, the decimal representation is rounded toward zero.""" # Extract sign first so it doesn't mess up the string digit count if s[0]: sign = '-' s = mpf_neg(s) else: sign = '' _sign, man, exp, bc = s if not man: return '', '0', 0 bitprec = int(dps * math.log(10,2)) + 10 # Cut down to size # TODO: account for precision when doing this exp_from_1 = exp + bc if abs(exp_from_1) > 3500: from libelefun import mpf_ln2, mpf_ln10 # Set b = int(exp * log(2)/log(10)) # If exp is huge, we must use high-precision arithmetic to # find the nearest power of ten expprec = bitcount(abs(exp)) + 5 tmp = from_int(exp) tmp = mpf_mul(tmp, mpf_ln2(expprec)) tmp = mpf_div(tmp, mpf_ln10(expprec), expprec) b = to_int(tmp) s = mpf_div(s, mpf_pow_int(ften, b, bitprec), bitprec) _sign, man, exp, bc = s exponent = b else: exponent = 0 # First, calculate mantissa digits by converting to a binary # fixed-point number and then converting that number to # a decimal fixed-point number. fixprec = max(bitprec - exp - bc, 0) fixdps = int(fixprec / math.log(10,2) + 0.5) sf = to_fixed(s, fixprec) sd = bin_to_radix(sf, fixprec, 10, fixdps) digits = numeral(sd, base=10, size=dps) exponent += len(digits) - fixdps - 1 return sign, digits, exponent
def to_bstr(x): sign, man, exp, bc = x return ['','-'][sign] + numeral(man, size=bitcount(man), base=2) + ("e%i" % exp)