2017年12月29日金曜日

固定小数点形式の

符号1ビット+n桁の整数部+m桁の小数点部
n=12、m=3
n=2、m=13
n=1、m=14
とか変なデータがある。そこで、小数点位置を任意に指定できる10進変換関数はないかと探すが、ないみたい。
 Decimalという関数の説明ページにたどり着いて、穴が開くほど読んでいたが、解決に至らない。

Python で小数点対応の N 進数から 10 進数に変換するプログラムを書いた

というページを見つけた。汎用関数になっているので、2進数を10進に変換するだけなので、小数部分の変換を書いてみた。
from decimal import *

data ='110'
sum0 =Decimal(0)
for (i,x) in enumerate(data) :
    sum0 += Decimal(x)*Decimal(2**(-(i+1)))
print (data,sum0)

内包表現にしてみた。
fractional =sum([(float(Decimal(x)*Decimal(2**(-(i+1))))) for (i,x) in enumerate(data)])
これ1行見たら、翌日にはどうやって変換しているかわからない.

  • 小数点第1位を取り出し、2^-1すると0.5が得られる。それにその数字を乗じる。1なら0.5、0なら0。
  • 小数点第2位を取り出し、2^-2すると0.25が得られる。それにその数字を乗じる。1なら0.25、0なら0。

それを桁数分繰り返す。
floatで実数として取り出す。取り出したのはリスト形式。なのでsumで合計を求める。
永久に1を超えられない数値が求まる。

 関数にした。16ビット限定だと。16進のデータdatahex(ex。0xb3f9)と、整数部分のビット数integer(ex。12)を引数に呼び出す。

def kotei(datahex,integer) :
        if (datahex & 0b1000000000000000 ) :
                I1=(~datahex ^ 0xffff)
                I0=bin(datahex)[3:(3+integer)]
                Integer=-(int(I0,2) ^ int(("1"*integer),2))
                F0= bin(I1)[(2+integer):]
                Fractional =-sum([(float(Decimal(x)*Decimal(2**(-(i+1))))) for (i,x) in enumerate(F0)])
        else:
                Integer=(datahex & 0b0111111111111111 )>> (15-integer)
                fdata3=str(bin((datahex & 0b0111111111111111 ) & int( '1' * (15-integer),2)))[2:]
                Fractional =sum([(float(Decimal(x)*Decimal(2**(-(i+1))))) for (i,x) in enumerate(fdata3)])
        #print Integer,Fractional,(Integer+Fractional)
        return(Integer+Fractional)

まちがっている。。。。 修正しました。
Integerは整数部分。負のときは反転し、LSBに1ビット足す。正のときは小数部分の桁分右にシフトするだけ。
fdata3は小数部の1,0を文字列で切り出す。
Fractionalは、小数点の演算。
整数部と小数部を加算して終了。

0 件のコメント:

コメントを投稿