简体   繁体   English

从float32转换为float时如何保持精度?

[英]How to retain precision when converting from float32 to float?

I have a numpy.float32 object that I want to encode as JSON. 我有一个要编码为JSON的numpy.float32对象。 The problem is that when I convert to a native python float , I lose the precision of the value. 问题是当我转换为本地python float ,我失去了值的精度。

Example: 例:

In [1]: import numpy as np
In [4]: np.float32(295.96).item()
Out[4]: 295.9599914550781

However, if I first convert to string, then to float, the precision is retained. 但是,如果我先转换为字符串,然后转换为浮点数,则将保留精度。

In [3]: float(str(np.float32(295.96)))
Out[3]: 295.96

Is there a way to retain my precision without having to go through a string first? 有没有一种方法可以保持我的精度而不必先经过字符串?

Why does str(np.float32(295.96)) seem to retain the precision but np.float32(295.96).item() (or float(np.float32(295.96)) or np.asscalar(np.float32(295.96)) ) does not? 为什么str(np.float32(295.96))似乎保持精度,但是np.float32(295.96).item() (或float(np.float32(295.96))np.asscalar(np.float32(295.96)) ) 才不是?

Note: I cannot assume that the precision will always be .01 . 注意:我不能假设精度将始终为.01 I need to retain the native precision of the data. 我需要保留数据的本机精度。

You incorrectly assume that what you see in console is what really happens. 您错误地认为在控制台中看到的是实际发生的情况。 The result you see (ie the rounding) is just for you = the one who looks at the console. 您看到的结果(即,四舍五入)仅适合您=查看控制台的人。 This is how printing of floats is implemented unfortunately (IMO confusing). 不幸的是,这就是浮法打印的方式(IMO令人困惑)。

The underlying float is always correct, eg 基础浮点数始终是正确的,例如

In [4]: a = np.float32(295.96)
In [5]: a
Out[5]: 295.95999
In [6]: import json
In [7]: json.dumps(a.item())
Out[7]: '295.9599914550781'

It's not possible to store 64 bits of precision in a 32-bit value. 无法在32位值中存储64位精度。 In python, float is 64 bit (what is referred to as a double in C). 在python中, float是64位(在C中称为double )。 As a demo, everything is OK with 64-bit floats: 作为一个演示,使用64位浮点数就可以了:

>>> d = 295.6; dn = np.float64(d)
>>> (d, dn)
(295.6, 295.95999999999998)  # numpy prints out more digits than python
>>> d == dn  # but these are still the same
True
>>> d - dn
0.0

But if you try and use 32 bits, you drop precision 但是,如果尝试使用32位,则会降低精度

>>> d = 295.96; fn = np.float32(d)
>>> (d, fn)
(295.96, 295.95999)
>>> d == fn
False
>>> d - fn
8.5449218545363692e-06

Why does str(np.float32(295.96)) seem to retain the precision 为什么str(np.float32(295.96))似乎保持精度

str(np.float32(295.96)) looks like it retains precision because np.float32.__str__ rounds (in base 10) for convenience. str(np.float32(295.96))看起来保留了精度,因为np.float32.__str__为方便起见四舍五入(以10为底)。 It just so happens that when rounded, it exactly matches the text you typed in your code. 碰巧的是,在四舍五入时,它与您在代码中键入的文本完全匹配。 As a result, it has exactly the same value. 结果,它具有完全相同的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM