2016-11-15 15 views
0


私は浮動小数点数を長さに変換しようとしていますが、ソケット経由で送る方法を見ています。私は、逆シリアル化できない番号をテストするためにFloatToIntメソッドを作成しました。
longにフロートから、それを変換し、それが正常に動作しますが、私は再び浮いて長いからそれを変換しようとすると、それは「非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

私はFloatToInt方法で値を充填した場合と同じ整数値を有するが

だからstr.decode(「進」)は、エラーをスローします。
私には何か不明なアイディアがありますか?

+0

あなたは「進」コーデックが何をするのか理解していますか? –

+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 

EDIT: PythonはCPUの浮動小数点を使用していますが、それは二つのタイプ

  • 単精度ている - "フロート"
  • 倍精度と呼ばれる - "ダブル" と呼ばれる

それはあなたがを使用できるようにPythonは、この例では「ダブル」を使用縫い目正しい値

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 

を取得するの代わり!f

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

ここでの唯一の問題は、10桁の10進数の浮動小数点数と10桁の10進数の浮動小数点数をアンパックしていることです。ですから、私はこれを梱包しています:22083.60066068796と解凍22083.6015625 – Lucian

+0

あなたは '.10f'をパックしません - ' .10f'はスクリーン上のテキストをフォーマットするためだけに使われます。結果を表示するには '.10f'を使用してください。おそらく正しいテキストが得られます。 – furas

+0

私は次のように印刷します:print "%.10f"%ret取得する:22083.6015625000ので丸めます。私はそれをパックし、それを正しく解凍する必要があります、私は高精度電圧mesurementsで働いています。 – Lucian

関連する問題