-1

我有一个问题,我需要将浮点数正确到小数点后 18 位。当我使用默认浮点数(数字)时,它只给我 12 位小数。

然后我做了 dir(float)

    ['__abs__', '__add__', '__class__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__',
 '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getformat__',
 '__getnewargs__', '__gt__', '__hash__', '__init__', '__int__', '__le__', '__long__', '__lt__', '__m
od__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__pos__', '__pow__', '__radd__', '
__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '_
_rmul__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__setformat__', '__sizeof__', '__s
tr__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', 'as_integer_ratio', 'conjugate', '
fromhex', 'hex', 'imag', 'is_integer', 'real']

在那个块中有一个叫做 __setformat__ 的东西。它的用途是什么?以及如何将其用于浮点精度设置?

我正在使用 python 2.7.5 x64。

4

2 回答 2

5

令我惊讶的是,这个论坛上的人们如何竭尽全力避免看到真正的问题,诚然,这个问题显然是对 python 非常陌生的人措辞非常糟糕。这是一个很好的新手问题,所以我会把事情说清楚。

显然,__setformat__对于“falloutx”的预期目的是无用的。打字:

>>> help(float.__setformat__)

会给任何需要解释的人一个答案,新手可能不会对此感兴趣。

隐式查询仍然有效。

如果我这样做:

>>> from math import pi
>>> print pi
3.14159265359

我只看到小数点后十二位。Python 使用双精度,所以我可以这样做:

>>> print "{:.16}".format(pi)
3.1415926535897931

这是正确的,除了尾随的“1”应该是“2”。这是因为双精度只能表示大约 16 个有效数字,而整数 '3' 算作一个有效数字。

所以要回答真正的问题:在内部,您有 16 个有效数字。这意味着对于 -1.0 < v < 1.0 范围内的值“v”,您可以显示的最佳值是 16 位小数。如果您的值有一个整数部分,这将降低可用的小数精度,对于非常大的值可能会完全消除它。

要查看完整精度,请使用上述字符串格式。

但是,可能会出现外观问题:

>>> print "{:.16f}".format(1.0)
1.0000000000000000

你可以这样做:

>>> print "{:.16f}".format(1.0).rstrip('0')
1.

另一个查询: 更改默认浮点打印格式对这个问题有一些有趣的方法。因此,例如,如果 print 语句的冗长困扰您,并且您真的希望看到至少一位小数精度,您可以这样做:

>>> class newfloat(float):
...   precision=4
...   def __str__(self):
...     s="{{:.{0}f}}".format(self.precision)
...     s=s.format(self)
...     if s.endswith('0'): s=s.rstrip('0')+'0'
...     return s
... 
>>> f=newfloat(pi)
>>> g=newfloat(1.0)
>>> print f,g
3.1416 1.0
>>> newfloat.precision=2
>>> print f,g
3.14 1.0

如果您正在使用 .format 构造进行大量字符串格式化,您可以通过定义一个类来获得相同的结果,如上所述,但将其命名为“_”。然后你这样做:

>>> "A {0} string with {1} custom float format {2}".format(*map(_,(1,2,pi)))
'A 1.0 string with 2.0 custom float format 3.14'
于 2015-06-18T00:27:43.843 回答
4

它只对 Python 测试套件有用;help(float.__setformat__)印刷:

float.__setformat__(typestr, fmt) -> None

您可能不想使用此功能。它的存在主要是为了在 Python 的测试套件中使用。

typestr必须是'double'or 'float'fmt必须是'unknown''IEEE, big-endian'或之一'IEEE, little-endian',此外,如果它看起来与底层 C 现实相匹配,则只能是后两者之一。

覆盖 C 级浮点类型的自动确定。这会影响浮点数与二进制字符串的转换方式。

还有一个float.__getformat__()getter 方法,用于相同的信息、相同的目的。

有关其使用的更多详细信息,请参阅float测试套件

使用该decimal模块可以获得更准确的十进制计算,但请查看sys.float_info有关您平台上的浮点数准确度的详细信息。例如,我的 64 位 Mac OS X 系统只能管理 15 位数字。

于 2013-09-04T07:04:45.493 回答