Python float __setformat__?

fal*_*utx -1 python floating-point python-2.7

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

然后我做了dir(浮动)

    ['__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']
Run Code Online (Sandbox Code Playgroud)

该块中有一些叫做__setformat__的东西.有什么用?以及如何使用它进行浮点精度设置?

我使用的是python 2.7.5 x64.

Mar*_*ers 5

它只适用于Python测试套件; help(float.__setformat__)打印:

float.__setformat__(typestr, fmt) -> None

您可能不想使用此功能.它主要存在于Python的测试套件中.

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

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

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

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

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


小智 5

让我感到惊讶的是,这个论坛上的人们如何竭尽全力避免看到真正的问题,诚然,这个问题的措辞很糟糕,显然是对 Python 非常陌生的人。这是一个很好的新手问题,所以我会让事情变得明确。

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

>>> help(float.__setformat__)
Run Code Online (Sandbox Code Playgroud)

会给任何需要解释的人一个答案,这是新手不可能合理地感兴趣的。

隐式查询仍然有效。

如果我这样做:

>>> from math import pi
>>> print pi
3.14159265359
Run Code Online (Sandbox Code Playgroud)

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

>>> print "{:.16}".format(pi)
3.1415926535897931
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

>>> print "{:.16f}".format(1.0)
1.0000000000000000
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

>>> print "{:.16f}".format(1.0).rstrip('0')
1.
Run Code Online (Sandbox Code Playgroud)

另一个查询: Change default float print format对这个问题有一些有趣的方法。因此,例如,如果打印语句的冗长困扰您,并且您确实希望看到至少一位小数精度,您可以这样做:

>>> 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
Run Code Online (Sandbox Code Playgroud)

如果您使用 .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'
Run Code Online (Sandbox Code Playgroud)