乱数と浮動小数点 - 2 / 3 -
BREW での浮動小数点演算と数学関数
浮動小数点演算はヘルパ関数を使うことになり面倒ですが、実は通常の C 言語の記法で浮動小数点演算と数学関数を扱える便利な方法があります。
BREW の浮動小数点演算
BREW のヘルパ関数関数呼び出しは、通常の C のプログラミングでは、コメントのように書きます。それでは、コメントのように書くと何が問題なのでしょうか。
double ret = FMUL(2.0, 3.14); //2.0 * 3.14 int ret2 = FLTTOINT(ret); // (int)ret
BREW では、浮動小数点に対して普通の四則演算や整数型へのキャストなどをすると、リンクエラーが発生します。
実際は、リンクエラーが発生する場合と、しない場合があります。
//推奨されないが、リンクされる。結果も正しい。 double ret = 2 * 3.14;
//携帯端末用にコンパイルする際にリンクエラー発生 int ret2 = (int)ret; // int 型へのキャスト
浮動小数点演算は、「コンパイラ組み込み関数」を使用するコードに置き換えられます。「コンパイラ組み込み関数」が、実機用のライブラリに存在するか否かの問題に帰着されます。
BREW 環境で通常の浮動小数点演算と数学関数を使用する方法
通常の C 言語の記法で浮動小数点の四則演算やキャスト、数学関数が使える方法を説明します。
アプレット構造体には浮動小数点の演算関数用に 2 つの変数を追加します。
■アプレット構造体の宣言
typedef struct MathApp { AEEApplet a; // アプレット構造体の先頭メンバは必ず AEEApplet 型にすること。 Common common; // 描画用 #if defined __arm signed int volatile _errno; unsigned int _fpstatus; #endif } MathApp;
次に、ライブラリ関数の再定義と、アプリの起動時に浮動小数点演算ライブラリの初期化関数を呼び出すコードなどを記述します。
■関数の宣言と、浮動小数点ライブラリの初期化
#if defined __arm #include <rt_misc.h> #include <errno.h> #include <rt_fp.h> #endif #if defined __arm #pragma import(__use_no_semihosting_swi) #endif #if defined __arm void __rt_raise(signed int signal, signed int type) { return; } signed int volatile* __rt_errno_addr(void) { MathApp* ap = (MathApp*)GETAPPINSTANCE(); return(&ap->_errno); } unsigned int* __rt_fp_status_addr(void) { MathApp* ap = (MathApp*)GETAPPINSTANCE(); return(&ap->_fpstatus); } #endif int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po,void ** ppObj) { *ppObj = NULL; if(ClsId == AEECLSID_MATHAPP){ if(AEEApplet_New(sizeof(MathApp), ClsId, pIShell,po,(IApplet**)ppObj, (AEEHANDLER)MathApp_HandleEvent,NULL) == TRUE) { #if defined __arm _fp_init();//浮動小数点ライブラリの初期化 #endif return AEE_SUCCESS; } } return EFAILED; }
以上で、BREW のヘルパ関数を使用せずに、通常の C 言語の記法で浮動小数点演算と数学関数が使えます。
詳細情報:浮動小数点演算と数学関数