将 ctype float 正确转换为 python float

Converting ctype float to python float properly

我通过 C 库收到 ctype c_float,我想将其转换为常规 python float.

问题是 ctype 使用 32 位精度,而 python 使用 64 位精度。

假设用户在 C 用户界面中输入了数字 1.9。该数字表示为 1.899999976158142。当我在 C 端打印时,会考虑这种表示形式,我得到 1.9.

的输出

然而,在 python 方面,当我将 c_float 转换为精度更高的 python 时,该数字将不会被视为 1.9 时打印,但改为 1.899999976158142

我该如何解决?

我找到了一个方法,但它有点笨拙(而且效率低得不必要),所以我希望有一个更优雅的解决方案:

float_c = ctypes.c_float(1.9)  # c_float(1.899999976158142)

float_32 = float_c.value  # 1.899999976158142
float_str = f"{float_32:g}"  # "1.9"
float_py = float(float_str)  # 1.9

由于精度只会在转换为字符串(打印和写入文件)期间成为问题,我可以忍受它并省略最后一步,但我发现将数字保留在其“有问题的”中是不雅的" 每次我可能想要打印它时都必须担心转换的状态。

相反,我认为在 C lib 和 python 之间的切换点转换一次它更干净,再也不用担心它了。

所以我应该像这样从 c_float 转换为 python 浮动还是有更好的方法?

一个可能的解决方法是使用 numpy 的 float32:

>>> float_c = ctypes.c_float(1.9)
>>> np.float32(float_c)
1.9

人们指出,从 float32 转换为 float64 的数字与 C 中存储的值完全相同,您需要知道原始数字才能满足您更精确的定义, 但您可以将结果数字四舍五入到与 C 相同的小数位数(或者您认为用户想要的),并且结果 float64 将更接近该值:

>>> import struct
>>> x=struct.unpack('f',struct.pack('f',1.9))[0] # trick to achieve converted number
>>> x
1.899999976158142
>>> y=round(x,7)  # or to whatever places you expect the user to enter
>>> y
1.9
>>> format(x,'.20f')
'1.89999997615814208984'
>>> format(y,'.20f')
'1.89999999999999991118'