【问题标题】:Reading a float from string从字符串中读取浮点数
【发布时间】:2012-06-15 21:05:09
【问题描述】:

我有一个简单的字符串,我想将它读入浮点数而不丢失任何可见信息,如下图所示:

s = '      1.0000\n'

当我执行f = float(s) 时,我得到f=1.0

如何骗取f=1.0000?

谢谢

【问题讨论】:

  • 1.0 === 1.0000
  • 这个问题与您最初提出的问题大不相同。
  • 没错,空格会起作用,但是可见我只是指数字。
  • 你想用1.0000做什么?
  • @Gumbo, 1.0 !== 1.000 在所有情况下。统计学家会在精度方面看到两者之间非常不同的含义。

标签: python string floating-point


【解决方案1】:

直接回答:你不能。根据设计,浮动是不精确的。虽然 python 的浮点数具有足够的精度来表示 1.0000,但它们永远不会表示“1-point-zero-zero-zero-zero”。很有可能,这和你需要的一样好。如果需要显示四位十进制数字,您始终可以使用字符串格式。

print '%.3f' % float(1.0000)

间接回答:使用decimal 模块。

from decimal import Decimal
d = Decimal('1.0000')

decimal 包旨在以任意精度处理所有这些问题。小数“1.0000”恰好是 1.0000,不多也不少。但是请注意,舍入的复杂性意味着您不能将 float 直接转换为 Decimal;您必须将字符串(或整数)传递给构造函数。

【讨论】:

  • 浮点数的精度或不精度与它无关。 浮点表示(根据定义)基本上以等效于科学记数法的方式实现:带有尾数和指数。由于每个数字都存储为 0.XXXXX 乘以 2 的 YYYY 次幂,因此小数点右侧的小数位没有意义。 Base-10 浮点系统(如 Python Decimal 类)使用内部变量来跟踪所需的精度位数,并在输出中重现这些位数,否则它们将完全相同。
  • 我不是在最严格的意义上使用“精度”,而是在“小数点右侧的有效数字”意义上。虽然 Python Decimal 类 可能 是十进制浮点系统,但事实上它确实支持“精确的未舍入十进制算术”。而且似乎跟踪精度的内部变量正是原始发布者正在寻找的。​​span>
【解决方案2】:
>>> 1.0 == 1.00 == 1.000
True

换句话说,您不会丢失任何信息——Python 认为浮点数小数部分的尾随零无关紧要。如果您需要非常具体地跟踪“有效数字的数量”,这也是可行的,但您需要向我们所有人解释您在 Python 的正常 float 之外想要完成的工作(例如,@987654323 Python标准库中的@与它有什么关系?等等,等等...)。

【讨论】:

  • 我知道他们是平等的,这就是为什么我明确地使用了“可见”这个词。我只想保留零以符合我的特殊标头标准。如果我不在阅读步骤中执行这些操作,我将不得不使用此信息重新创建相同的标题。这很容易,只需使用格式化运算符进行打印。谢谢你的解释。
  • @gsever:如果你想用精确的格式来往返一个数字,也许只存储输入字符串和浮点表示是最简单的?但是,如果您没有对值进行任何花哨的数学运算,我认为Decimal 可能是您想要的答案。
  • 不,至少在科学术语中是 1.0 != 1.00。 1.00 的精度为 +-0.01,而 1.0 的精度为 +-0.1
  • @dalolilogm:这是一个表示的问题(阅读字符串格式),而不是空值的重要性。
  • @dallilogm,实数的数学理论(从高中代数到微积分等任何东西的基础)没有“精度”(或“有效数字”或“公差”任何等价物区间算术的简化)。毫无疑问,在科学和工程中,我们确实需要用误差范围来增加测量值,尽管它可能会遇到困难,但是,作为一种表示法,声明尾随零的数量是重要的并没有帮助。如果 a=1.0 且 b=1.00,那么 a+b 是什么? a-b? a*b? a/b?如果我们连这个都做不到,那有什么好处呢?!
【解决方案3】:

在我重新发明轮子的时候尽情享受吧! ;)

如果您希望对象的reprsentation(它在shell 中显示的方式)具有1.0000 的形式,那么您可能需要更改float 的__repr__ 方法。如果您希望将对象打印到文件或屏幕上,您需要更改__str__ 方法。这是一个兼具两者的课程。

class ExactFloat(float):
    def __repr__(self):
        return '%.4f' % self
    __str__ = __repr__


# usage of the shiny new class to follow..
>>> f = ExactFloat('    1.0000\n')
>>> f
1.0000
>>> print f
1.0000

现在还有无数其他 better 方法可以做到这一点,但就像我说的,我喜欢 重新发明轮子:)

【讨论】:

  • 我分享你对车轮上的改造的看法,因为我今天做了同样的事情。见stackoverflow.com/questions/1449139/simple-object-recognition。对我来说是一个非常优雅的解决方案,但是我们可能需要添加一些香料以使其更通用。可能我会忘记 0,然后建议使用 @Chris B.。
【解决方案4】:

这是@Simon Edwards 的ExactFloat 的一个更闪亮的版本,它计算句点后的位数,并在数字转换为字符串时显示该位数。

import re

class ExactFloat(float):
    def __init__(self, str_value):
        float.__init__(self, str_value)
        mo = re.match("^\d+\.(\d+)", str_value)
        self.digits_after_period = len(mo.group(1))

    def __repr__(self):
        return '%.*f' % (self.digits_after_period, self)

    def __str__(self):
        return self.__repr__()


print ExactFloat("1.000")
print ExactFloat("1.0")
print ExactFloat("23.234500")

例子:

$ python exactfloat.py
1.000
1.0
23.234500

【讨论】:

  • 这确实很闪亮。感谢您花时间创建这个很好的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 2020-08-04
  • 1970-01-01
相关资源
最近更新 更多