cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

半精度浮動小数点(2バイト)と単精度浮動小数点(4バイト)のC言語での変換方法を調べる

Tiのマイコンで使われているfloat_t型は2バイトで与えられています。一般に知られているfloat型は4バイトの単精度浮動小数点です。
2バイトで表現される浮動小数点は半精度浮動小数点(half)と呼ばれ、最近では、レンダリング機械学習の用途で需要が増えているそうです。
しかし、普通のC言語には簡単に変換する方法は提供されていません。これを簡単に変換する方法を調べてみたいと思います。

半精度浮動小数点について

半精度浮動小数点数 - Wikipedia

素敵な情報源

  1. C++用の半精度(16bit)浮動小数点ライブラリって無いですか? 環… - 人力検索はてな
  2. 単精度浮動小数点数 - Wikiwand
  3. Search · half float · GitHub

OpenEXRで使われているライブラリは、ilmbase-2.2.0の中のHalfフォルダにあります。BSDライセンスとのことなので自由に使えそうです。ただし、c++実装です。
matlabが配布しているソースコードは、mex前提みたいなので借りてきて使うのは面倒そうです。

c言語向けでは、githubにあるramenhutさんのhalfライブラリがc++で書かれてはいるのですが、きれいで簡単でよさそうです。

というわけで、ramemhutさんのライブラリを改造して試してみたいと思います。

GitHub - ramenhut/half: IEEE 754 16-bit Float

テストコード。ただし、メンバー変数のm_uiFormatをpublicにしてある。

#include <iostream>
#include "half.h"

using namespace std;

int main(void){
    // Here your code !
    FLOAT16 a = 0.222;
    FLOAT16 b = 0;
    unsigned char upper, lower;
        
    upper = ((unsigned short)a.m_uiFormat >> 8) & 0xff;
    lower = (unsigned short)a.m_uiFormat & 0xff;
    b.m_uiFormat = (upper << 8) + lower;
    
    cout << a << endl;
    cout << (int)lower << " " << (int)upper << endl;
    cout << b << endl;
    
    return 0;
}

結果
0.221924
26 51
0.221924