在 x86 上,a = 1.1
, 打印 a 还是 1.1
但是在 arm 平台上,a=1.1
, 打印 a 是1.1000000001
字样。
最后协议通过 json 格式发送,协议要求是.1f 的格式。 json 序列化通过标准库里的,然后就整不出来了。
请教一下大家,怎么解决, 谢谢。
1
P0P 2016-02-02 17:05:16 +08:00
最后转换成字符串喽。。。 `a = '0.1f' % a`
|
2
ryanking8215 OP @lazydomino 转换成字符串是可以的,但是 json 序列化后是 string 了,不是 number 了。
|
3
P0P 2016-02-02 17:18:56 +08:00 1
网上说是因为某些 arm 芯片没有 hardware float module 的原因,需要特别编译版本的 python
|
4
neoblackcap 2016-02-02 17:19:35 +08:00
这个其实不算是 Python 的问题,所有浮点都是这样的,因为二进制不能精确表示所有小数。
你可以选择 decimal.Decimal 来替代 float ,在 json.load 里面启用 parse_float 参数就可以了 甚至你可以传入一个你自己定义的 JSONEncoder 子类来实现你想要的效果 |
5
neoblackcap 2016-02-02 17:20:42 +08:00
补充一下,是 json.loads ,当然 parse_float 这个形参在 json.load 里面也是支持的
|
6
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 |
7
zhicheng 2016-02-02 17:47:56 +08:00
用 decimal 。
|
8
ryanking8215 OP @lhbc 请教一下交叉编译的方法,有没有特殊的做法?我的交叉编译器是 gcc 4.4.1, 也是 armv7l 的
|
9
lhbc 2016-02-02 18:10:38 +08:00
@ryanking8215 我是直接用 Archlinux, 自带 Python 3.5.1
|
10
proudzhu 2016-02-02 18:30:30 +08:00 via Android
为啥不直接传 * 10 之后的整形数据
|
11
fy 2016-02-02 22:00:58 +08:00
要高精度,你需要 decimal 特别是处理钱
|
12
ryanking8215 OP @neoblackcap 谢谢,但我要用的是 json.dumps
|
13
ryanking8215 OP 各位,这个问题解决了,解决方法是在 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"的方法,但是改了没用,因为是在编译时确定的。 |