python默认字符_关于字符串:str(x)的Python默认行为

我依赖于一些使用decimal类的代码,因为它需要精确到一定数量的小数位。有些函数允许输入是浮动的,因为它与代码基的其他部分的接口方式。要将它们转换为十进制对象,它使用

1mydec = decimal.Decimal(str(x))

其中x是作为输入的浮点。我的问题是,是否有人知道"str"方法应用于float的标准是什么?

例如,取数字2.1234512。它在内部存储为2.1234511999999999,因为浮点数是如何表示的。

1

2

3

4

5>>> x = 2.12345119999999999

>>> x

2.1234511999999999

>>> str(x)

'2.1234512'

好的,在这种情况下,str(x)执行的操作类似于"%.6f""%x"。这是我的代码转换为小数的方式的问题。采取以下措施:

1

2

3

4>>> d = decimal.Decimal('2.12345119999999999')

>>> ds = decimal.Decimal(str(2.12345119999999999))

>>> d - ds

Decimal('-1E-17')

所以,如果我有float,2.1234511999999999,我想把它传递给decimal,用str()把它转换成一个字符串,会得到错误的答案。我需要知道str(x)的规则是什么,这些规则决定了格式是什么,因为我需要确定是否需要重新编写此代码以避免此错误(请注意,这可能是正常的,因为例如,一旦我们有了十进制对象,代码可能会四舍五入到小数点后10位)。

在python的文档中一定有一些规则,希望这里的某个人能指向我。谢谢!

如果没有x.__str__()或x.__repr__(),那么str(x)返回x.__str__()或x.__repr__(),这些完全取决于手头的对象。

str通常返回更为人类可读的表示。如果您想要完全准确,可以使用repr,它将返回'2.12345119999999999'。

请看浮点数和字符串转换的奇怪行为

再说一次,如果您的原始编号是2.1234512,而2.12345119999999999只是内部存储的方式,那么str的"缩短"表示是否更精确?

@托比亚斯·库克:是的,我曾经看到过这个功能,它的编号是2.1234512,但我可能看到的是2.123451199999999。

在python源中,查找"include/floatobject.h"。字符串转换的精度是在注释后从顶部开始设置几行,并对选择进行一些解释:

1

2

3

4

5/* The str() precision PyFloat_STR_PRECISION is chosen so that in most cases,

the rounding noise created by various operations is suppressed, while

giving plenty of precision for practical use. */

#define PyFloat_STR_PRECISION 12

如果你需要不同的东西,你可以选择重建。任何更改都将更改浮点数和复数的格式。请参见./objects/complexobject.c和./objects/floatobject.c。此外,您还可以比较这两个文件中repr和str转换双精度的不同。

是的,就是这样!谢谢!

注意这个数字在python 2.6和python2.7之间发生了变化。如果你想要最大的精度,你应该使用repr()而不是str(),它总是给你一个表示,在双精度的范围内尽可能精确地表示数字。

重建python当然不是解决这个问题的正确方法。

@Svenmarnach:据我所知,在python 2的生命周期中,PyFloat_STR_PRECISION并没有改变:2.6和2.7都是12。当大值的串化转换为科学记数法时,会有一些小的变化,但是浮点的str仍然基于小数展开的12个最重要的数字。在python 3.2和更高版本中,这一点发生了变化,其中repr和str现在对于float是相同的。

@马克迪金森:谢谢你的纠正。我似乎记得这个变化是在3.1和2.7中应用的,但我的记忆显然是错误的。:)也许这是最基本的表示方式……

@Svenmarnach:是的:float->string和string->float转换的新算法进入了python 3.1,然后(稍后)进入了python 2.7,repr输出的差异是变化中最用户可见的部分。从理论上讲,可能也会出现影响str的角点情况(例如,在操作系统未完全正确进行舍入的情况下,接近一半的情况);实际上,我不知道任何此类角点情况。

这里有几个问题值得讨论,但总结是:您不能提取尚未存储在系统中的信息。

如果您取了一个十进制数并将其存储为一个浮点,那么您将丢失信息,因为大多数具有有限位数的十进制(以10为基数)数不能使用以2为基数(二进制)的有限位数存储。

如前所述,str(a_float)实际上称为a_float.__str__()。如文件所述,该方法的目的是

return a string containing a nicely printable representation of an object

对于float案件没有特别的定义。我的意见是,为了您的目的,您应该考虑__str__的行为是未定义的,因为没有关于它的正式文档-当前的实现可以随时更改。

如果没有原始字符串,则无法从float对象中提取十进制表示的缺失数字。您所能做的就是使用字符串格式(您提到的)按可预见的方式进行四舍五入:

Decimal( "{0:.5f}".format(a_float) )

您还可以使用resulting_string.rstrip("0")删除右侧的0。同样,此方法不会恢复已丢失的信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值