如何将整数解释为浮点数

内西W.

我正在尝试使用用C#编写的DLL与激光通信。我使用ctypes模块成功加载了DLL函数。我要使用的函数有一个如下所示的声明:

LONG LJV7IF_GetStorageData( LONG lDeviceId, 
                            LJV7IF_GET_STORAGE_REQ* pReq,
                            LJV7IF_STORAGE_INFO* pStorageInfo,
                            LJV7IF_GET_STORAGE_RSP* pRsp, 
                            DWORD* pdwData, 
                            DWORD dwDataSize );

我想通过dword指针pdwData访问数据。激光通过如下结构发送其存储的数据:

Bytes |  Meaning  |   Types
 0-3  |   time    |    dword          
  4   |  judgment |    byte
  5   | meas info |    byte
 ...  |    ...    |    ... 
 8-11 |   data    |    float

这就是我使用功能的方式:

self.dll = WinDLL( "LJV7_IF.dll" )
self._getStoredData = self.dll.LJV7IF_GetStorageData
self._getStoredData.restype = c_int32
self._getStoredData.argstypes = [ c_int32,
                                  POINTER( GET_STORAGE_REQ ),
                                  POINTER( STORAGE_INFO ),
                                  POINTER( GET_STORAGE_RSP ),
                                  POINTER( c_uint32 ),
                                  c_uint32 ]
dataSize = 132
dataBuffer = c_uint32 * ( dataSize / 4 )
outputData_p = POINTER( c_uint32 )( dataBuffer() )
self._getStoredData( deviceID,
                     byref( myStruct ),
                     byref( storageInfo ),
                     byref( storageResponse ),
                     outputData_p ),
                     dataSize )

为简洁起见,没有详细介绍myStruct,storageInfo和storageResponse(它们在其他DLL函数调用中使用,它们似乎工作得很好)。

我的问题是,当我尝试访问时outputData_p[ 2 ],python给我返回一个int,例如1066192077。这正是我问他的。但我希望将int解释/转换为float,应该是1.1或类似的值(不记得确切的值)。使用hex() -> bytes() -> struct.unpack( )任何一种都不将其强制转换为浮动(我得到1066192077.00)我能做什么 ??

孙ry

注意:如果您在搜索如何将整数转换为单精度浮点数时到达此处,请忽略此答案的其余部分,仅使用JF Sebastian注释中的代码。它使用struct模块而不是ctypes,它更简单并且始终可用,而ctypes可选地包含在Python的标准库中:

import struct

def float_from_integer(integer):
    return struct.unpack('!f', struct.pack('!I', integer))[0]

assert float_from_integer(1066192077) == 1.100000023841858

您可以使用ctypesfrom_buffer方法将数组解释为其他类型通常,您可以将具有可写缓冲区接口的任何对象传递给此方法,而不仅仅是ctypes实例-例如bytearrayNumPy数组。

例如:

>>> from ctypes import *
>>> int_array = (c_int * 4)(1, 2, 3, 4)
>>> n_doubles = sizeof(int_array) // sizeof(c_double)
>>> array_t = c_double * n_doubles
>>> double_array = array_t.from_buffer(int_array)

它仍然是相同的字节,只是重新解释为两个8字节的双精度:

>>> bytes(double_array)
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'
>>> double_array[:]
[4.2439915824e-314, 8.4879831653e-314]

由于此数组是通过调用from_buffer而不是通过创建的from_buffer_copy,因此实际上是一个与原始数组共享相同缓冲区的视图。例如,如果将最后两个整数移到最前面,则中的值double_array也会交换:

>>> int_array[:] = [3, 4, 1, 2]
>>> double_array[:]
[8.4879831653e-314, 4.2439915824e-314]

请注意,您的示例代码有错字。定义函数参数类型的属性名称是argtypes,不是argstypes

self._getStoredData.argstypes = [ c_int32,
                    ^^^^^^^^^

定义此原型不是严格必要的,但建议这样做。当调用from_param函数时,它使ctypes为每个参数调用相应的方法。如果没有原型,则默认参数处理将接受ctypes实例,并自动将字符串转换为char *orwchar_t *以及将整数转换为Cint值;否则会引发一个ArgumentError

您可以按以下方式定义打包的(即不使用对齐填充)数据记录:

class LaserData(Structure):
    _pack_ = 1
    _fields_ = (('time',      c_uint),
                ('judgement', c_byte),
                ('meas_info', c_byte * 3),
                ('data',      c_float))

这是一个示例类,将通用数据参数类型定义为POINTER(c_byte),并将结果作为由设备实例确定的记录数组返回。显然,这只是该类实际定义方式的要点,因为我对此API几乎一无所知。

class LJV7IF(object):
    # loading the DLL and defining prototypes should be done
    # only once, so we do this in the class (or module) definition.
    _dll = WinDLL("LJV7_IF")
    _dll.LJV7IF_Initialize()

    _dll.LJV7IF_GetStorageData.restype = c_long
    _dll.LJV7IF_GetStorageData.argtypes = (c_long,
                                           POINTER(GET_STORAGE_REQ),
                                           POINTER(STORAGE_INFO),
                                           POINTER(GET_STORAGE_RSP),
                                           POINTER(c_byte),
                                           c_uint)

    def __init__(self, device_id, record_type):
        self.device_id = device_id
        self.record_type = record_type

    def get_storage_data(self, count):
        storage_req = GET_STORAGE_REQ()
        storage_info = STORAGE_INFO()
        storage_rsp = GET_STORAGE_RSP()
        data_size = sizeof(self.record_type) * count
        data = (c_byte * data_size)()
        result = self._dll.LJV7IF_GetStorageData(self.device_id,
                                                 byref(storage_req),
                                                 byref(storage_info),
                                                 byref(storage_rsp),
                                                 data,
                                                 data_size)
        if result < 0: # assume negative means an error.
            raise DeviceError(self.device_id) # an Exception subclass.
        return (self.record_type * count).from_buffer(data)

例如:

if __name__ == '__main__':
    laser = LJV7IF(LASER_DEVICE_ID, LaserData)
    for record in laser.get_storage_data(11):
        print(record.data)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

python:如何将整数显示为浮点数?

PHP 将数字解释为浮点数,即使它们小于 INT_MAX

如何将字符串解析为变量/函数/浮点数/整数赋值/值?

如何将浮点数转换为整数?

如何将多个整数更改为浮点数?

Golang如何将整数和浮点数相乘

如何将整数转换为浮点数?

如何将四个带符号的浮点数打包为一个整数?

如何将scanf的输入限制为整数和浮点数(一般为数字)

如何将字符串编码的浮点数组解组为浮点数组?

重新解释为浮点数时可以指定字节顺序吗?

pandas DataFrame将整数显示为浮点数

将大浮点数舍入为整数

我们如何将浮点数拆分为其整数和小数部分?

如何将具有 n 个小数位的整数转换为浮点数

如何将CString转换为整数和浮点数?

如何将浮点数乘以整数来分配变量

如何将浮点数转换为十进制整数乘以2的幂?

如何将熊猫系列中的数字转换为整数或浮点数?

如何将浮点数数组转换为唯一整数数组?

当两个都是变量时,如何将浮点数除以整数?

如何将整数或浮点数转换为 S16.16 定点格式

如何将浮点数元组转换为整数元组

如何防止Gson将整数表示为浮点数

如何判断浮点数是否为整数?

当输入预计为整数时如何检测浮点数?

如何将浮点数转换为任何浮点数的XE-Y

如何将巨大的头部分配数组设置为特定的浮点数C ++

如何将文本文件读取为浮点数列表?