python3 float 精度问题

2016-02-02 16:49:51 +08:00
 ryanking8215

在 x86 上,a = 1.1, 打印 a 还是 1.1
但是在 arm 平台上,a=1.1, 打印 a 是1.1000000001字样。

最后协议通过 json 格式发送,协议要求是.1f 的格式。 json 序列化通过标准库里的,然后就整不出来了。

请教一下大家,怎么解决, 谢谢。

6573 次点击
所在节点    Python
13 条回复
P0P
2016-02-02 17:05:16 +08:00
最后转换成字符串喽。。。 `a = '0.1f' % a`
ryanking8215
2016-02-02 17:07:18 +08:00
@lazydomino 转换成字符串是可以的,但是 json 序列化后是 string 了,不是 number 了。
P0P
2016-02-02 17:18:56 +08:00
网上说是因为某些 arm 芯片没有 hardware float module 的原因,需要特别编译版本的 python
neoblackcap
2016-02-02 17:19:35 +08:00
这个其实不算是 Python 的问题,所有浮点都是这样的,因为二进制不能精确表示所有小数。

你可以选择 decimal.Decimal 来替代 float ,在 json.load 里面启用 parse_float 参数就可以了

甚至你可以传入一个你自己定义的 JSONEncoder 子类来实现你想要的效果
neoblackcap
2016-02-02 17:20:42 +08:00
补充一下,是 json.loads ,当然 parse_float 这个形参在 json.load 里面也是支持的
lhbc
2016-02-02 17:22:22 +08:00
$ uname -a
Linux RaspberryPi 4.1.17-1-ARCH #1 SMP Mon Feb 1 18:55:49 MST 2016 armv7l GNU/Linux

$ python
Python 3.5.1 (default, Dec 11 2015, 05:35:45)
[GCC 5.3.0] on linux
>>> a = 1.1
>>> print(a)
1.1
zhicheng
2016-02-02 17:47:56 +08:00
用 decimal 。
ryanking8215
2016-02-02 17:50:33 +08:00
@lhbc 请教一下交叉编译的方法,有没有特殊的做法?我的交叉编译器是 gcc 4.4.1, 也是 armv7l 的
lhbc
2016-02-02 18:10:38 +08:00
@ryanking8215 我是直接用 Archlinux, 自带 Python 3.5.1
proudzhu
2016-02-02 18:30:30 +08:00
为啥不直接传 * 10 之后的整形数据
fy
2016-02-02 22:00:58 +08:00
要高精度,你需要 decimal 特别是处理钱
ryanking8215
2016-02-03 08:48:20 +08:00
@neoblackcap 谢谢,但我要用的是 json.dumps
ryanking8215
2016-02-04 14:38:09 +08:00
各位,这个问题解决了,解决方法是在 CONFIG_SITE 里增加'ac_cv_little_endian_double=yes'。

详情追溯:
仔细一想,和"精度"没有关系,本来 float 里存的就是那个数据,又没有参与运算, decimal 也解决不了问题,只不过浮点数变量显示的不是我要的格式。于是去"floatobject.c"里碰碰运气,发现它通过一个“ PY_NO_SHORT_FLOAT_REPR ”宏来指定 repr 的方法。

废话不多说的,关键字: "floatobject.c"->"PY_NO_SHORT_FLOAT_REPR"->"DOUBLE_IS_LITTLE_ENDIAN_IEEE754"->"ac_cv_little_endian_double"

从 sys.float_repr_style 里也可以得到"short"或者” legacy"的方法,但是改了没用,因为是在编译时确定的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/255038

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX