我有一个简单的字符串,我想读入浮点数而不会丢失任何可见信息,如下所示:
s = ' 1.0000\n'
当我f = float(s)
时,我得到f=1.0
如何欺骗这个获取f=1.0000
?
谢谢
答案 0 :(得分:9)
直接回答:你不能。根据设计,浮子是不精确的。虽然python的浮点数具有足够的精度来表示1.0000,但它们永远不会表示“1点零 - 零 - 零”。机会是,这是你所需要的。如果需要显示四位十进制数字,则可以始终使用字符串格式。
print '%.3f' % float(1.0000)
间接答案:使用decimal
模块。
from decimal import Decimal
d = Decimal('1.0000')
decimal
包旨在以任意精度处理所有这些问题。十进制“1.0000”完全 1.0000,不多也不少。但请注意,舍入的复杂性意味着您无法从float
直接转换为Decimal
;你必须将一个字符串(或一个整数)传递给构造函数。
答案 1 :(得分:5)
>>> 1.0 == 1.00 == 1.000
True
换句话说,你没有丢失任何信息 - Python认为浮点数小数部分中的尾随零是无关紧要的。如果你需要非常具体地跟踪“有效数字的数量”,这也是可行的,但是你需要向我们解释你在Python正常float
之外要完成的所有事情(例如, Python标准库中的decimal
与它有什么关系?等等......)。
答案 2 :(得分:1)
在重新发明轮子的时候放纵我吧! ;)
如果您希望对象的repr
发送(它在shell中显示的方式)具有1.0000的形式,那么您可能需要更改浮点数的__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
方法可以做到这一点,但就像我说的那样,我喜欢
重新发明轮子:))
答案 3 :(得分:1)
这是@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