在python中将无符号整数转换为浮点

在python中将无符号整数转换为浮点,python,ieee-754,floating-point-conversion,Python,Ieee 754,Floating Point Conversion,我编写了一个套接字服务器,从一些设备读取数据。读取数据后,对字节应用二进制移位。之后,我得到一个整数值,例如1108304047,我想把这个数字转换成ieee754float 35.844417572021484。我用struct.unpack找到了一些解决方案,但在我看来它并不合理。首先我们将数字转换为字符串,然后转换为浮点 Java中有没有类似于Float.intBitsToFloat(1108304047)的捷径 我用struct.unpack找到的解决方案相当长。它包括字符串转换、子字符

我编写了一个套接字服务器,从一些设备读取数据。读取数据后,对字节应用二进制移位。之后,我得到一个整数值,例如
1108304047
,我想把这个数字转换成ieee754float 35.844417572021484。我用struct.unpack找到了一些解决方案,但在我看来它并不合理。首先我们将数字转换为字符串,然后转换为浮点

Java中有没有类似于
Float.intBitsToFloat(1108304047)
的捷径

我用struct.unpack找到的解决方案相当长。它包括字符串转换、子字符串获取、零填充等

def convert_to_float(value):

    return struct.unpack("!f", hex(value)[2:].zfill(8).decode('hex'))[0]

正如您在Java中所看到的,他们使用结构来完成这项任务

/*
 * Find the float corresponding to a given bit pattern
*/
JNIEXPORT jfloat JNICALL
Java_java_lang_Float_intBitsToFloat(JNIEnv *env, jclass unused, jint v)
{
    union {
        int i;
        float f;
    } u;
    u.i = (long)v;
    return (jfloat)u.f;
}
在Python中,这种方式是不可能的,因此需要使用

此模块在Python值和表示为Python字符串的C结构之间执行转换

首先,数字转换为
long

packed_v = struct.pack('>l', b)
然后解包到
float

f = struct.unpack('>f', packed_v)[0]
这与Java中的类似

def intBitsToFloat(b):
   s = struct.pack('>l', b)
   return struct.unpack('>f', s)[0]
如果我错了,请纠正。

ldexp
frexp
正数分解。 如果您可以处理多达2-16个相对误差量,则可以使用基本算法和
ld/frexp
分解来表示转换的两面

请注意,这比struct hack慢得多,struct hack可以更简洁地表示为
struct.unpack('f',struct.pack('I',value))

这是分解方法

def to_bits(x):
  man, exp = math.frexp(x)
  return int((2 * man + (exp + 125)) * 0x800000)

def from_bits(y):
  y -= 0x3e800000
  return math.ldexp(
      float(0x800000 + y & 0x7fffff) / 0x1000000, 
      (y - 0x800000) >> 23)
虽然
from_bits
函数看起来更可怕,但实际上它只不过是
to_bits
的倒数,经过修改,我们只执行一个浮点除法(不是出于速度考虑,只是因为当我们确实需要使用浮点数的机器表示时,这应该是我们的思维方式)。因此,我将重点解释正向转换

起源 回想一下,(正)IEEE 754浮点数表示为有偏指数及其尾数的元组。下23位m表示尾数,上8位e(减去最高有效位,我们假设它始终为零)表示指数,因此

x=(1+m/223)*2e-127


让man'=m/223和exp'=e-127,然后0可能重复的“我发现了一些使用struct.unpack的解决方案,但我觉得它不合理”为什么不呢?这就是如何在一行中解决这个问题。“首先我们将数字转换为字符串,然后再转换为浮点。”从概念上讲,它与其说是一个字符串,不如说是一个字节序列(如果您使用的是Python 3,这一点很清楚)。这也正是您的Java代码段所做的,只是拼写不同。我看不到任何字符串转换。我的观点是,它们都没有真正进行“字符串”转换。Python需要一个字节缓冲区,Python中最简单的形式是(字节)string.Python的
struct
模块最适合用于C风格的
struct
union
(在Java中可以找到)。这完全是我想要的。对于更长的数字,请尝试
float64=460718241880017408;
打印struct.unpack('d',struct.pack('Q',int(bin(float64)),0))[0]
--结果是
1.0