为了账号安全,请及时绑定邮箱和手机立即绑定

为什么repr(float)在Google App Engine上返回的位数要比其他数字多

为什么repr(float)在Google App Engine上返回的位数要比其他数字多

慕运维8079593 2021-05-05 18:42:03
我有一些简单的代码,如下所示a = 0.8889print repr(a)print str(a)我在几种不同的系统(包括python 2.7.12〜2.7.14,作为提示输入或脚本)上进行了尝试,总是得到如下结果0.88890.8889这是一个例子。但是,在App Engine(运行时Python 2.7.12)上,我得到了0.888900000000000020.8889我知道repr()趋势会更加精确。问题是为什么App Engine的行为会有所不同。它是否依赖底层硬件?背景:这个事实让我很烦,因为在将浮点数转换为json时,我不必要地放宽了位数。更新:原来这是GAE运行时的错误。正如Mark所评论的,根本原因是未配置sys.float_repr_style。GAE支持团队在此处创建了错误报告。Update2: 它已于2018/08/19修复。即使尚未宣布。
查看完整描述

2 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

值的sys.float_repr_style值为“旧版”,这是GAE在构建时设置的选项,无法更改。

此版本的repr算法以前是Python 2.7之前使用的格式,该格式先计算17个有效数字,然后将输出基于这17个数字(适当时将尾随零分隔为零)


查看完整回答
反对 回复 2021-05-25
?
Qyouu

TA贡献1786条经验 获得超11个赞

显然,正如@abarnert在评论中提到的那样,GAE env在后台做了一些工作,其中之一是提高了所使用的浮点数的精度。


您可以注意到的第一件事是:


>>> a = 0.88890000000000002

>>> print a

0.8889

这意味着多余的数字是无用的。


您可以使用Decimal模块来重现这种情况:


>>> from decimal import *

>>> Context(prec=17).create_decimal_from_float(0.899).__str__()

'0.89900000000000002'

有趣的是,GAE似乎试图模拟约17的浮点精度(float没有特定的十进制精度,因为它们表示为浮点数)。如果> 17,则会得到更多的小数,如果少于,则数字不够精确。


使用的优点Decimal是浮点错误更少,尽管看起来repr()有一些问题。


查看以下更多扩展示例以提供更多上下文:


>>> from decimal import *

>>> Context(prec=16).create_decimal_from_float(0.899).__str__()

'0.8990000000000000'

>>> Context(prec=17).create_decimal_from_float(0.899).__str__()

'0.89900000000000002'

>>> Context(prec=18).create_decimal_from_float(0.899).__str__()

'0.899000000000000021'

>>> repr(float(1.0000000000000003)).__str__()

'1.0000000000000002'

>>> Context(prec=17).create_decimal_from_float(1.0000000000000003).__str__()

'1.0000000000000002'

>>> repr(float(1.0000000000000002)).__str__()

'1.0000000000000002'

>>> Context(prec=17).create_decimal_from_float(1.0000000000000002).__str__()

'1.0000000000000002'

>>> repr(float(1.0000000000000001)).__str__()

'1.0'

>>> Context(prec=17).create_decimal_from_float(1.0000000000000001).__str__()

'1'

最后,由python float 0.899表示的实际数字是:


>>> from decimal import *

>>> Decimal(float(0.899))

Decimal('0.89900000000000002131628207280300557613372802734375')

因此,最后,reprGAE中提供的表示非常精确。


查看完整回答
反对 回复 2021-05-25
  • 2 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信