猿问

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

我有一些简单的代码,如下所示


a = 0.8889

print repr(a)

print str(a)

我在几种不同的系统(包括python 2.7.12〜2.7.14,作为提示输入或脚本)上进行了尝试,总是得到如下结果


0.8889

0.8889

这是一个例子。


但是,在App Engine(运行时Python 2.7.12)上,我得到了


0.88890000000000002

0.8889

我知道repr()趋势会更加精确。问题是为什么App Engine的行为会有所不同。它是否依赖底层硬件?


背景:


这个事实让我很烦,因为在将浮点数转换为json时,我不必要地放宽了位数。


更新:


原来这是GAE运行时的错误。正如Mark所评论的,根本原因是未配置sys.float_repr_style。GAE支持团队在此处创建了错误报告。


Update2: 它已于2018/08/19修复。即使尚未宣布。


慕运维8079593
浏览 136回答 2
2回答

慕容3067478

值的sys.float_repr_style值为“旧版”,这是GAE在构建时设置的选项,无法更改。此版本的repr算法以前是Python 2.7之前使用的格式,该格式先计算17个有效数字,然后将输出基于这17个数字(适当时将尾随零分隔为零)

Qyouu

显然,正如@abarnert在评论中提到的那样,GAE env在后台做了一些工作,其中之一是提高了所使用的浮点数的精度。您可以注意到的第一件事是:>>> a = 0.88890000000000002>>> print a0.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中提供的表示非常精确。
随时随地看视频慕课网APP

相关分类

Python
我要回答