浮動小数点の指数部の考え方

Pythonは小数は倍精度浮動小数点方式により定義するのが一般的です。倍精度浮動小数点型では2進数で表したものを、1.XXXとなるようにビット列をシフトし、シフトした桁数を指数部として表します。ところで指数部は11bitを使った表します。このとき、指数部はマイナスの場合もあるので、1023だけ下駄を履かせます。この1023をバイアス(偏り)といいます。

画像1

ここで、10進数を2進数の仮数部と指数部にわけて変換するプログラムを作ってみました。

#5 10進数を仮数部と指数部に変換する
def base_dec2bin(dec):
   nary = ''
   while dec > 0:
       nary = str(dec % 2) + nary
       dec //= 2
   return nary

def ieee(dec):
   nary=base_dec2bin(dec)
   frac='1.'
   for i in range(1,len(nary)):
       frac+=nary[i]
   bias=len(nary)-1+1023
   return frac,nary,bias,base_dec2bin(bias)


for i in range(1,101,10):
   frac,nary,bias,expon=ieee(i)
   print(f'{i:>3}  {nary:<10} {frac:<10}  {bias:<4} :{expon}') 

画像2

詳しくは、Pythonの小数型で扱うことができる数の大きさ に書きました。

ここれわからないのが、指数部が11bitで、正の部分を見ると最大2の1023乗になることです。これは次の通り、概算で10の308乗となります。

import math
math.log10(2**1023)

#307.95368556425274

IPアドレスのIPv6がとんでもなく大きな数字だとして10の38乗なので、308乗というのはクレージーな数字です。倍精度浮動小数点方式で表現できる正の数値の最大値は仮数部で1が53個並んで、その後に0が255個程度並ぶのですから、勿体ないような気がします。64bitを有効活用するうえで、仮数部の割合をもっと増やさない理由があってのでしょうか。とても不思議です。

いいなと思ったら応援しよう!