2016-11-15 77 views
0


我想将一个浮点数转换为long并返回,以查看如何通过套接字发送它。我制作了FloatToInt方法来测试我无法反序列化的数字。
当从浮点数转换它长时间工作正常,但是当我试图把它从长转换再次浮起来抛出“非十六进制数字发现”整数浮法thorks TypeError:找到非十六进制数字

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:float:22083.6006606880
FloatToInt:Packed: 'F\xac\x874'
FloatToInt:Integers: [70, 172, 135, 52]

IntToFloat:Integers: [52, 135, 172, 70]
IntToFloat:Hex chars: '4\x87\xacF'

Traceback (most recent call last):
........
TypeError: Non-hexadecimal digit found

所以str.decode('hex')会抛出一个错误,虽然我有和FloatToInt方法中打包值相同的整数值。
你有什么想法我失踪?
谢谢

+0

你知道什么是“十六进制”编解码器吗? –

+0

使用为编码注册的'hex'(2字节)编解码器解码obj ?! – Lucian

+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浮点但它有两种类型

  • 单精度 - 被称为 “漂浮”
  • 双精度 - 所谓的 “双”

它在这个例子中使用Python“double”,所以你可以使用!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 
+0

这里唯一的问题是我打包一个.10f,所以10位小数点浮点数,我打开一个稍微不同的7位小数浮点数。所以,我打包这个:22083.60066068796和解包22083.6015625 – Lucian

+0

你不包装'.10f' - '.10f'只用于在屏幕上格式化文本。使用'.10f'来显示结果,并且可能会得到正确的文本。 – furas

+0

如果我打印它:print“%.10f”%ret我会得到:22083.6015625000所以它是圆形的。我需要打包并正确打开包装,我正在使用高精度电压测量。 – Lucian