计算出有效小数点以格式化浮点数

时间:2015-12-14 04:01:37

标签: python floating-point precision

我发现this涵盖了如何抑制科学记数法,但我想更进一步,并计算出格式化字符串(即表示数字所需的小数点数)

到目前为止,我的想法是假设一个非常高的分辨率(在这个例子中为20),并按照接受的答案here中的建议减少尾随零。是否有更好的方法来实现这一目标?

      Plot.iframe = document.getElementById("plot");

注意,我也不想要科学记数法(使用格式字符串>>> f = 0.00000008 >>> s = '{:.20f}'.format(f) >>> s '0.00000008000000000000' >>> s.rstrip('0') '0.00000008' 可以获得)。

1 个答案:

答案 0 :(得分:0)

浮点数的最大有效位数为15(功率与此分开)。因此,考虑到更多的数字是没有意义的,因为它们是不对的。知道给定数字的10的幂会告诉你在前面填充多少个零。

如果您要格式化的内容永远不会超过一个,那么以下内容就足够了:

from math import log10

def floatformat(f):
    pwr = log10(f)
    return '{:.0{}f}'.format(f, int(abs(pwr)) + 15).rstrip('0')

但是如果你正在解析任何可能的浮点值,你将不得不稍微处理大数字以获得尾随零而不是随机不准确的数字。

def floatformat(f):
    sigs = 15  # number of accurate digits that a float can contain
    pwr = log10(f)

    if pwr > sigs:  # power above accurate digits
         s = '{:.{}f}'.format(f / 10 ** int(pwr), sigs)
         s = s.replace('.', '')  # remove decimal point, no longer necessary here
         s = s + '0' * (int(pwr) - sigs)  # add in trailing zeros

    elif 0 < pwr <= sigs:  # power within accurate digits
        s = '{:.{}f}'.format(f, sigs - int(pwr)).rstrip('0')

    else:  # power below accurate digits
        s = '{:.0{}f}'.format(f, int(abs(pwr)) + sigs).rstrip('0')

    if s[-1] == '.': s = s[:-1]  # remove trailing decimal point if needed
    return s

所有这一切都是保持准确的数字,然后在没有科学记数法的情况下将它们拖曳以获得正确的数据。

示例:

>>> floatformat(0.00000008)
'0.00000008'
>>> floatformat(0.0000000000000000000000000000008)
'0.0000000000000000000000000000008'
>>> floatformat(0.00000000000000000000000000000080067)
'0.00000000000000000000000000000080067'
>>> floatformat(2.31451103e7)
'23145110.3'
>>> floatformat(2.31451103e3)
'2314.51103'
>>> 935.16087e203 == float(floatformat(935.16087e203))  # conversion check to see if power is handled correctly
True
>>> import sys
>>> floatformat(sys.float_info.max)
'179769313486231600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
>>> floatformat(sys.float_info.min)
'0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072'