整数浮点数Thorws TypeError:找到非十六进制数字

时间:2016-11-15 15:50:09

标签: python serialization


我试图将浮点数转换为long和back只是为了看看如何通过套接字发送它。我制作FloatToInt方法只是为了测试那个我无法反序列化的数字 当它从float转换为long时它工作正常,但是当我尝试将它从long转换为float时它会抛出“找到非十六进制数字”

def FloatToInt(num):
    num = 22083.60066068796
    print "FloatToInt:float:%.10f" %num 
    packed = struct.pack('!f', num)
    print 'FloatToInt:Packed: %s' % repr(packed)
    integers = [ord(c) for c in packed]
    print 'FloatToInt:Integers: %s' % repr(integers)
    val = int(0)
    for i in integers:
        val |= i
        val = val << 8
    return val

def IntToFloat(num):
    #val = struct.unpack('!f', num.decode('hex'))[0]
    #return val
    intArr = []
    while num > 0:
        val = num & 0xFF
        if val > 0:
            intArr.append(int(val))
        num = num >> 8
    print 'IntToFloat:Integers: %s' % repr(intArr)
    chars = [chr(c) for c in intArr]
    str = ""
    for ch in chars:
        str += ch
    print 'IntToFloat:Hex chars: %s' % repr(str)
    ret = struct.unpack('!f', str.decode('hex'))[0]
    return ret

输出:

  

FloatToInt:浮动:22083.6006606880
  FloatToInt:打包:'F \ xac \ x874'
  FloatToInt:整数:[70,172,135,52]

  IntToFloat:整数:[52,135,172,70]
  IntToFloat:十六进制字符:'4 \ x87 \ xacF'

  追溯(最近的呼叫最后):
  ........
  TypeError:找到非十六进制数字

所以str.decode('hex')抛出一个错误,虽然我有与在FloatToInt方法中打包值时相同的整数值。
你有什么想法我错过了什么吗? 谢谢

1 个答案:

答案 0 :(得分:1)

decode('hex')用于解码此'0487AC0F'之类的字符串。

print( '0487AC0F'.decode('hex') )

但您的代码中不需要decode()。您必须仅反转intArr中的元素才能获得正确的结果。

顺便说一句。要通过套接字发送float,您只需要pack / unpack - 您不必创建long int - 因为套接字只能发送字符串或字节。要通过套接字发送long int,您需要pack / unpack将其转换为字符串/字节。

import struct

def FloatToInt(num):
    num = 22083.60066068796
    print "FloatToInt:float:%.10f" %num

    packed = struct.pack('!f', num)
    print 'FloatToInt:Packed: %s' % repr(packed)

    integers = [ord(c) for c in packed]
    print 'FloatToInt:Integers: %s' % repr(integers)

    val = int(0)
    for i in integers:
        val |= i
        val = val << 8

    return val

def IntToFloat(num):
    intArr = []

    while num > 0:
        val = num & 0xFF
        if val > 0:
            intArr.append(val)
        num = num >> 8

    # you have to reverse numbers
    intArr = list(reversed(intArr))

    print 'IntToFloat:Integers: %s' % repr(intArr)

    text = "".join([chr(c) for c in intArr])
    #chars = [chr(c) for c in intArr]
    #text = ""
    #for ch in chars:
    #    text += ch

    print 'IntToFloat:Hex chars: %s' % repr(text)

    # you don't need decode('hex')
    ret = struct.unpack('!f', text)[0]

    return ret

num = 22083.60066068796
r = FloatToInt(num)
print '   FloatToInt:', r 
r = IntToFloat(r) 
print '   IntToFloat:', r

编辑: Python使用CPU浮动,但它有两种类型

  • 单精度 - 称为&#34; float&#34;
  • 双精度 - 称为&#34; double&#34;

它连接Python使用&#34; double&#34;在此示例中,您可以使用!d代替!f来获取正确的值

import struct

num = 22083.60066068796
print "   float: %.10f" % num

packed = struct.pack('!d', num)
print '  packed: %s' % repr(packed)

ret = struct.unpack('!d', packed)[0]
print "unpacked: %.10f" %num

   float: 22083.6006606880
  packed: '@\xd5\x90\xe6q9\x86\xb2'
unpacked: 22083.6006606880
先前代码中的

"double"

 import struct

def FloatToInt(num):

    print "FloatToInt:    float: %.10f" % num

    packed = struct.pack('!d', num)
    print 'FloatToInt:   Packed: %s' % repr(packed)

    integers = [ord(c) for c in packed]
    print 'FloatToInt: Integers: %s' % integers

    val = int(0)
    for i in integers:
        val |= i
        val = val << 8

    print 'FloatToInt:   result: %d\n' % val

    return val

def IntToFloat(num):

    print 'IntToFloat:  integer: %d\n' % num

    intArr = []

    while num > 0:
        val = num & 0xFF
        if val > 0:
            intArr.append(val)
        num = num >> 8

    intArr = list(reversed(intArr))

    print 'IntToFloat: Integers: %s' % intArr

    text = "".join([chr(c) for c in intArr])
    print 'IntToFloat:Hex chars: %s' % repr(text)

    ret = struct.unpack('!d', text)[0]
    print 'IntToFloat:   result: %.10f\n' % ret

    return ret

num = 22083.60066068796
r = FloatToInt(num)
r = IntToFloat(r)

FloatToInt:    float: 22083.6006606880
FloatToInt:   Packed: '@\xd5\x90\xe6q9\x86\xb2'
FloatToInt: Integers: [64, 213, 144, 230, 113, 57, 134, 178]
FloatToInt:   result: 1195980674018107109888

IntToFloat:  integer: 1195980674018107109888
IntToFloat: Integers: [64L, 213L, 144L, 230L, 113L, 57L, 134L, 178L]
IntToFloat:Hex chars: '@\xd5\x90\xe6q9\x86\xb2'
IntToFloat:   result: 22083.6006606880