将 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'
我通过 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'