Python 在将float转换为str时,如何检查默认的十进制精度?

Python 在将float转换为str时,如何检查默认的十进制精度?,python,string,floating-point,Python,String,Floating Point,将浮点转换为str时,我可以指定要显示的小数点数量 '%.6f' % 0.1 > '0.100000' '%.6f' % .12345678901234567890 > '0.123457' 但在Python2.7中,当对float调用str时,它似乎默认为最多12个小数点 str(0.1) >'0.1' str(.12345678901234567890) >'0.123456789012' 定义/记录的小数点最大值在哪里?我可以通过编程获得这个数字吗?我认为pyt

浮点
转换为
str
时,我可以指定要显示的小数点数量

'%.6f' % 0.1
> '0.100000'
'%.6f' % .12345678901234567890
> '0.123457'
但在Python2.7中,当对
float
调用
str
时,它似乎默认为最多12个小数点

str(0.1)
>'0.1'
str(.12345678901234567890)
>'0.123456789012'

定义/记录的小数点最大值在哪里?我可以通过编程获得这个数字吗?

我认为python语言规范中不存在这个数字。但是,cpython实现确实指定了它。该函数将浮点转换为字符串,最终使用
'r'
格式化程序调用一个帮助函数,该函数最终调用一个实用函数,将格式硬编码为
格式(float,.16g')
。可以看到这些代码。请注意,这是针对python3.6的

>>> import math
>>> str(math.pi*4)
12.5663706144
给出16位的最大有效位数(十进制前后)。在python2.7实现中,该值似乎被硬编码为
.12g
。至于发生这种情况的原因(可以找到有点缺乏文档)

因此,如果您试图获取打印时数字的格式长度,只需使用
.12g
获取其长度即可

def len_when_displayed(n):
     return len(format(n, '.12g'))

好的,如果您正在寻找一种纯python的方法来实现这一点,那么您可以使用

len(str(.12345678901234567890).split('.')[1])
>>>> 12
我在文档中找不到它,如果我找到了,我会把它添加到这里,但是如果你想事先知道的话,这是一个至少可以返回精度长度的方法

正如您所说,即使在输入更大的浮点时,它似乎总是
12


根据我所能发现的,这个数字可能是高度可变的,在这些情况下,从经验上找到它似乎是最可靠的方法。我要做的就是定义一个简单的方法

def max_floating_point():
    counter = 0
    current_length = 0
    str_rep = '.1'
    while(counter <= current_length):
        str_rep += '1'
        current_length = len(str(float(str_rep)).split('.')[1])
        counter += 1

    return current_length

显示的小数数将有很大的不同,并且没有办法预测在纯Python中显示多少小数。一些库,如
numpy
允许您设置输出精度

这仅仅是因为环境问题

链接的相关部分讨论Python如何选择显示浮动

Python只打印机器存储的二进制近似值的真正十进制值的十进制近似值

Python通过显示舍入值来保持位数的可控性

现在,这里存在重叠的可能性:

有趣的是,有许多不同的十进制数共享相同的近似二进制分数

选择要显示哪些十进制值的方法在Python3.1中发生了更改(但最后一句话暗示这可能是一个实现细节)

例如,数字0.1和0.100000000000001都是 近似值为3602879701896397/2**55。因为所有这些都是十进制的 值共享相同的近似值,其中任何一个都可以是 显示时仍保留不变值(repr(x))==x

历史上,Python提示符和内置的repr()函数 选择一个具有17个有效数字的0.100000000000001。 从Python3.1开始,Python(在大多数系统上)现在能够 选择其中最短的,只需显示0.1


通过查看转换后的随机数的输出,我无法理解
str()
的长度是如何确定的,例如在Python 3.6.6下:

>>> str(.123456789123456789123456789)
'0.12345678912345678'
>>> str(.111111111111111111111111111)
'0.1111111111111111'
您可以选择实际模拟您真实情况的代码:

import random
maxdec=max(map(lambda x:len(str(x)),filter(lambda x:x>.1,[random.random() for i in range(99)])))-2
在这里,我们正在测试转换后(.1,1)开放区间内~90个随机数的长度(并从左侧推导
0.
,从而得出
-2
)。
64位linux上的Python 2.7.5给了我12位,Python 3.4.8和3.6.6给了我17位。

如何将
'.16g'
等同于12位小数?@modesitt:我想你误解了代码。在Python版本>=3.2和Python 2.7中,在大多数机器上,
float_repr
根本不使用固定数量的有效数字。任何地方都没有
.16g
,而且从来没有(在Python2.6和更早版本中,使用了
.17g
repr
返回小数位数的最短字符串,该字符串保证在舍入到偶数的情况下返回到原始浮点值。不过,对于Python2.x的.12g被硬编码为Python
str
(而不是
repr
),您是对的。最好在
中演示一些东西,因为3.1中对浮点表示的更改被后传到了2.7FWIW,即“12”(这是特定于Python2.x、Python3.1和更早版本的)来自这里:。这在Python 3.2中发生了变化。@MarkDickinson谢谢,现在如果有一种方法可以从Python本身检查PyFloat_STR_精度值(假设我们知道我们使用的是cpython)@C_Z_,那么您是否必须处理仅检查版本还不够好的情况?从Python一开始就固定了12位数字的使用(至少在1993年发布的Python v0.9.8中有)。它直到Python3.2才改变,在Python3.2中它变得无关紧要,因为
str
不再将其输出基于固定数量的有效数字。请注意,当浮点的
repr
更改为使用17个有效数字而不是12个有效数字时,Python2.0中发生了变化。str的精度保持不变,不过.Hmmm,“Python只打印机器存储的二进制近似值的真正十进制近似值的十进制近似值”似乎有问题。我称之为精确的二进制浮点值,而不是二进制近似值。“…到机器存储的二进制的真正十进制值”听起来更清楚。浮点数的分配方式可能会产生一些舍入,但存储的值本身是精确的。@chux我同意,文档在这方面似乎有点不正确。为什么要用
import random
maxdec=max(map(lambda x:len(str(x)),filter(lambda x:x>.1,[random.random() for i in range(99)])))-2