单精度大端浮点值到Python的浮点数(双精度,大端)

Fab*_*ano 2 python arduino

我需要通过串行线(RS-232)接收来自Arduino的十六进制编码单精度大端浮点值.如何将它们转换为具有双精度的大端的Python浮点数?

Arduino发送类似"8192323E"的东西,在Python中我希望有0.174387.我发现" 将十六进制转换为浮动 "但似乎所有这些都不适用于单精度浮点数.

从链接页面看,这很有希望:

from ctypes import *

def convert(s):
    i = int(s, 16)                   # convert from hex to a Python int
    cp = pointer(c_int(i))           # make this into a c integer
    fp = cast(cp, POINTER(c_float))  # cast the int pointer to a float pointer
    return fp.contents.value         # dereference the pointer, get the float
Run Code Online (Sandbox Code Playgroud)

但它仍然不适用于我的单精度浮子.

在Java(Processing)中,我已经能够做到这一点:

float decodeFloat(String inString) {
  byte [] inData = new byte[4];

  inString = inString.substring(2, 10); // discard the leading "f:"
  inData[0] = (byte) unhex(inString.substring(0, 2));
  inData[1] = (byte) unhex(inString.substring(2, 4));
  inData[2] = (byte) unhex(inString.substring(4, 6));
  inData[3] = (byte) unhex(inString.substring(6, 8));

  int intbits = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);
  //unhex(inString.substring(0, 8));
  return Float.intBitsToFloat(intbits);
}
Run Code Online (Sandbox Code Playgroud)

供您参考,这是在Arduino上运行的C代码,它实现了十六进制编码.

void serialFloatPrint(float f) {
  byte * b = (byte *) &f;
  Serial.print("f:");
  for(int i=0; i<4; i++) {

    byte b1 = (b[i] >> 4) & 0x0f;
    byte b2 = (b[i] & 0x0f);

    char c1 = (b1 < 10) ? ('0' + b1) : 'A' + b1 - 10;
    char c2 = (b2 < 10) ? ('0' + b2) : 'A' + b2 - 10;

    Serial.print(c1);
    Serial.print(c2);
  }
}
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 5

Ignacio Vazquez-Abrams的答案为基础,

import binascii
import struct

text='8192323E'
print(struct.unpack('<f',binascii.unhexlify(text))[0])
# 0.17438699305057526
Run Code Online (Sandbox Code Playgroud)