Python格式字符串和浮点表示

2024-06-16 11:16:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用一些处理格式化用户存储的浮点数以供人类显示的就地代码。你知道吗

当前的实现是这样做的:

"{0:.24f}".format(some_floating_point).rstrip('0')

这是有道理的,而且在大多数情况下都很好。但是当面对一个值时,比如0.0003,事情就不那么顺利了。你知道吗

>>> "{0:.24f}".format(0.0003).rstrip('0')
'0.000299999999999999973719'

进一步的研究表明Python似乎根据请求的位数改变了底层的表示?你知道吗

>>> "{0:.15f}".format(0.0003)
'0.000300000000000'
>>> "{0:.20f}".format(0.0003)
'0.00029999999999999997'

我的假设是单精度vs双精度。你知道吗

用户输入这些值,这些值以double形式存储在数据库中,稍后再次呈现表单时,该字段中会预填充相同的值。因此,我需要这些表示的1:1映射。你知道吗

因此,我的问题是:什么是优雅的,更重要的是安全的方式来处理这种行为?到目前为止,我最大的努力是使用log10,但用它来表达并不理想。你知道吗

编辑:正如Prune所指出的,这个值实际上并没有改变,而是由格式所做的舍入将导致一组9变成0(d'oh)。这种行为在当时是有道理的,但我仍然没有找到解决办法。你知道吗


Tags: 代码用户format情况some人类事情point
1条回答
网友
1楼 · 发布于 2024-06-16 11:16:14

您正在接收存储的号码。0.0003不能完全作为二进制分数存储。举例说明:

>>> 0.00029999999999999997 == 0.0003
True

打印格式将数字四舍五入到最低有效位。双重精度只会把问题推向更右边。要完全“解决”以10为基数的问题,您需要切换到十进制算法,或者为足够接近更简单值的数字(小数部分中9或0的可疑字符串)构建自己的字符串处理程序。你知道吗


下面是一个函数的开始。我用0.0004测试了它,它存储为一根头发,大于0.0004;9的情况留作练习:-)。你知道吗

def str_round(x):
    size = 6
    nines = '9'*size
    zeros = '0'*size

    str = "{0:.24f}".format(x).rstrip('0')
    str_len = len(str)
    print str, str_len

    if nines in str:
        # replace leading digit with one more
        pos = str.index(nines)
        # ADD CODE HERE
        # Turn the leading portion into an integer;
        #   increment and convert back to zero-leading string.
        # Fill out the rest with zeros.

    elif zeros in str:
        # Change all trailing digits to 0
        pos = str.index(zeros)
        str = str[:pos] + '0'*(str_len - pos)

    return str

print str_round(0.0004)

相关问题 更多 >