2016-11-15 1 views
0


float 번호를 길게 변환하려고 시도하고 있습니다. 소켓을 통해 전송하는 방법을 알고 싶습니다. 내가 deserialize 할 수없는 번호를 테스트하기 위해 FloatToInt 메소드를 만들었습니다.
길이로 부동 소수점에서 변환이 잘 작동하지만 내가 다시 떠 긴에서 변환 할 때 그것은 "비 16 진수 발견"부동 소수점 형식 오류 : 16 진수가 아닌 숫자가 표시됨

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

"16 진수"코덱의 기능에 대해 알고 있습니까? –

+0

인코딩에 등록 된 'hex'(2 바이트) 코덱을 사용하여 obj를 디코딩합니까?! – Lucian

+0

하지만 그게 무슨 뜻인지 알겠습니까? –

답변

1

decode('hex')'0487AC0F'과 같은 문자열을 디코딩하는 데 사용됩니다.

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

코드에는 decode()이 필요하지 않습니다. 올바른 결과를 얻으려면 intArr에있는 요소 만 되돌려 야합니다.

BTW. 소켓을 통해 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 

편집 : 파이썬은 CPU의 부동 소수점을 사용하지만 두 가지 유형

  • 단 정밀도가 - "부동"
  • 배정도라고 - "더블"라고

이 예제에서 파이썬은 "double"을 사용하므로을 사용할 수 있습니다. 대신 !f의 392,926,754,127,897,003,210는 올바른 값

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 

를 얻을 수 있습니다. 앞의 코드

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) 

에서

float: 22083.6006606880 
    packed: '@\xd5\x90\xe6q9\x86\xb2' 
unpacked: 22083.6006606880 

"double" .

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 그래서 반올림됩니다. 그것을 포장하고 올바르게 포장해야합니다, 나는 고정밀 전압 mesurements와 함께 일하고 있습니다. – Lucian

관련 문제