Cベース設計 3分間クッキング(2) ――任意ビット幅浮動小数点
インド風のカレーにはナンやチャパティがよく合うと思う.ナンはパン,チャパティは薄焼きパンのようなもので,ちぎってカレーといっしょに食べる.買い物のとき,ナンはよく見かけるがチャパティはなかなかお目にかからない.どちらかというと,筆者はチャパティが好きで,作りかたを調べてみたら簡単そうなので,自分で作るようになった.
チャパティの作りかた
小麦粉+塩+水→こねる→寝かせる→のばす→焼く
小麦粉は薄力粉でもだいじょうぶ.塩加減は,小指の先ほどの塩でチャパティ3枚分くらい.ある程度こねたら,丸めて30分ほど寝かせる.この「寝かせる」という工程が重要らしい.寝ている間に小麦粉に含まれるプロテアーゼやアミラーゼなどの分解酵素が働いて,小麦に含まれるたんぱく質のグリアジンとグルテニンがからまり合い,グルテンを形成しているのだそうだ.グリアジンは「伸び」を,グルテニンは「弾力」を担当していて,これらの量の調整で同じ小麦が,うどん,パン,ぎょうざ,てんぷら,お菓子に利用されている.
* * *
組み込み機器に使用される浮動小数点演算も,処理に合わせて指数部のビット幅と仮数部のビット幅を調整することで,性能や面積,消費電力の最適値を検討する余地がある.受信処理用の浮動小数点演算と3 次元グラフィックス処理用のそれでは,必要なビット幅が異なる.ただし,任意ワード長の浮動小数点を簡単に扱える環境がないと,なかなかめんどうな作業でもある.
リスト1は,C++ テンプレートを利用してIEEEの単精度浮動小数点の精度を代入時に削ることにより,任意ワード長の浮動小数点をモデル化してみたものである.こうすることで,既存のアルゴリズム記述の浮動小数点宣言部分などの書き換えのみで処理精度を落としてみることができる.リスト1の29~30行目が任意ワード長浮動小数点の宣言で,その中身が1~24行目.2行目のfloat宣言が値を格納する実体.5行目からが代入演算子のオーバロードで,6~8行目で各パートに分離し,10~17行目で値が0以外のときの指数部の範囲を処理する.18行目が仮数部のワード長の切り捨て.19~20行目で三つの値をまとめている.32行目の代入では,aは指数部が飽和して値が65534になるが,bは飽和しない.34行目の代入では,aは3.14148,bは3.14159となる.
この例ではIEEEで定義されている不正規化数や無限大,NaN(非数)などは定義していない.実際のコーディングではほかの演算子の定義も含めて,使用するハードウェアに合わせてモデル化する.ただし,NaNは組み込み用途の小型の浮動小数点演算では扱わないことが多い.
チャパティは手軽に作れるが,ナン(NaN)は卵やイースト菌,ヨーグルトも加えてパンを作るように,オーブンで本格的に作らなくてはならない.
1 template <int _EXP,int _MNT> struct my_float {
2 float value;
3 my_float(){}
4
5 float operator=(float x){
6 int sgn = *((int *)&x) & 0x80000000;
7 int exp = *((int *)&x) & 0x7f800000;
8 int mntsa =*((int *)&x) & 0x007fffff;
9
10 if(exp==0&&mntsa==0){
11 }else if(exp >((0x7f+((1<<(_EXP-1))-1))<<23)){
12 exp =((0x7f+((1<<(_EXP-1))-1))<<23);
13 mntsa=0x007fffff;
14 }else if(exp <((0x7f-((1<<(_EXP-1))-1))<<23)){
15 exp =((0x7f-((1<<(_EXP-1))-1))<<23);
16 mntsa=0x007fffff;
17 }
18 mntsa &= (0x007fffff << (23- _MNT));
19 int tmp = sgn | exp | mntsa;
20 value = *((float *)&tmp);
21 return(x);
22 }
23 operator float(){ return(value); }
24 };
25
26 #include <iostream>
27 using namespace std;
28 main(){
29 my_float<5,14> a;
30 my_float<8,22> b;
31
32 a=b= 100000.0;
33 cout << a <<" "<< b << endl;
34 a=b= 3.141592653;
35 cout << a <<" "<< b << endl;
36 }
(本コラムはDESIGN WAVE MAGAZINE 2004年3月号に掲載されました)
◆筆者プロフィール◆
さめしま・まさひろ.高速ディジタル回路のコンサルティングやEDA ツール関係のしごとに従事.