繁体   English   中英

将float转换为str时,如何检查默认的小数精度?

[英]How do I check the default decimal precision when converting float to str?

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

'%.6f' % 0.1
> '0.100000'
'%.6f' % .12345678901234567890
> '0.123457'

但是,当简单地调用strfloat在Python 2.7,它似乎默认为12小数点最多

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

这个最大小数点数定义/记录在哪里? 我能以编程方式获取此号码吗?

显示的小数位数差异很大,并且无法预测纯Python中显示的小数位数。 numpy这样的库允许你设置输出的精度。

这仅仅是因为浮点表示局限性

该链接的相关部分讨论了Python如何选择显示浮点数。

Python仅将十进制近似值打印到机器存储的二进制近似值的真实十进制值

Python通过显示舍入值来保持可管理的位数

现在,这里有可能重叠:

有趣的是,有许多不同的十进制数,它们具有相同的最接近的近似二进制分数

用于选择要显示的十进制值的方法在Python 3.1中已更改(但最后一句意味着这可能是一个实现细节)。

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

从历史上看,Python提示符和内置的repr()函数将选择具有17位有效数字的0.10000000000000001。 从Python 3.1开始,Python(在大多数系统上)现在能够选择最短的这些并且只显示0.1。

我不相信这在python语言规范中存在。 但是,cpython实现确实指定了它。 float_repr()函数将float转换为字符串,最终使用'r'格式化程序调用辅助函数,该函数最终调用一个实用程序函数,该函数将格式硬编码为format(float, '.16g') 这段代码可以在这里看到。 请注意,这适用于python3.6。

>>> import math
>>> str(math.pi*4)
12.5663706144

给出最大数量的表示位数(小数点前后),看起来在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

这将返回当前系统的最大长度表示,

print max_floating_point()
>>>> 12

通过查看转换后的随机数的输出,我无法理解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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM