【问题标题】:Why does float() cut off trailing zeros?为什么 float() 会切断尾随零?
【发布时间】:2016-03-22 01:00:28
【问题描述】:

该代码成功地将一个包含许多数字的大文件裁剪为几个带有数字的较小文本文件,但它产生了一个有趣的怪癖。

所有数字都应保留四位小数,如 2.7400,但它们打印为 2.74。

这是来自文件的 sn-p

0.96
0.53
0.70
0.53
0.88
0.97

为什么会这样?有没有办法解决这个问题,或者这只是 float() 的一个怪癖?

from itertools import islice

def number_difference(iterable):
    return float(iterable[-1].strip('\n')) - float(iterable[0].strip('\n'))

def file_crop(big_fname, chunk_fname, no_lines):
    with open(big_fname, 'r') as big_file:
        big_file.readline()
        ifile = 0
        while True:
            data = list(islice(big_file, no_lines))
            if not data:
                break
            with open('{}_{}.locs'.format(chunk_fname, ifile), 'w') as small_file:
                offset = int(float(data[0].strip('\n')))
    map(lambda x: str(float(x.strip('\n')) - offset) + '\n', data)
    small_file.write('{} {} L\n'.format(len(data), number_difference(data)))
        small_file.write(''.join(map(lambda x: str(round((float(x.strip('\n')) - offset),4)) + '\n', data)))
            ifile += 1

【问题讨论】:

  • 2.74 和 2.7400 的 float 表示是相同的。在转换为float 后,无法知道在原始字符串表示中使用了多少额外的无关零。
  • A float 代表一个数字,尾随零不是数字的属性。 2.74 = 2.7400。

标签: python math floating-point numbers decimal


【解决方案1】:

您可以通过格式化输出来保留零:

例如:如果输出为0.96,

x= 0.96
"{0:.4f}".format(x)

输出:

'0.9600'

虽然输出将是一个字符串..

下面的文章可能是一个很好的阅读: https://docs.python.org/2/tutorial/floatingpoint.html

它解释了为什么 Python 以上述格式显示浮点数。

【讨论】:

  • 这没有回答问题的“为什么”部分
【解决方案2】:

浮点数只是python(和其他编程语言)中的近似值……例如,十进制数被计算为二进制值。很难找到大多数以 10 为底的操作的确切值

仔细查看此链接后,您会明白为什么 python 没有为您在 base 2 中转换的操作提供准确的值

https://docs.python.org/2/tutorial/floatingpoint.html

使用打印也可以完成这项工作

print("%.4f" % 0.96) or
whatever_file.write("%.4f" % 0.96)

【讨论】:

    【解决方案3】:

    IEEE 754 浮点数(其中floatbinary64)并非旨在保存精度信息。如果你需要这样做,那么你应该改用decimal.Decimal

    >>> decimal.Decimal('0.70')
    Decimal('0.70')
    >>> print decimal.Decimal('0.70')
    0.70
    

    查看decimal documentation了解完整详情。

    【讨论】:

    • 谢谢!我会研究'decimal.Decimal'
    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多