● 計算

数学関数

数学関数も算術演算と同様に、値をレジスタスタックへロードしてから計算を行います。結果を引数の変数に上書きする数学関数はありません。上書きさせる必要がある場合は、引数と結果格納先に同じアドレスを指定します。
関数は、リファレンスの「数学関数」を参照してください。


例.極座標を直交座標に変換(3次元)

#include "floatex.h"

void        cnv_3d(PFLOATEX r,PFLOATEX phi,PFLOATEX theta, /* r 、φ 、θ */
                PFLOATEX px,PFLOATEX py,PFLOATEX pz)
{
    FLOATEX     sn_p,cs_p,sn_t,cs_t;
    FLOATEX     t;

    floatex_sincos(phi,sn_p,cs_p);   /* sin φ、cos φ */
    floatex_sincos(theta,sn_t,cs_t); /* sin θ、cos θ */

    floatex_emul(r,cs_t,t);
    floatex_emul(t,cs_p,px); /* x = r・cos θ・cos φ */
    floatex_emul(t,sn_p,py); /* y = r・cos θ・sin φ */
    floatex_emul(r,sn_t,pz); /* z = r・sin θ */
}


引数が NaN の場合

引数の内容が NaN の場合、次の規則で処理を行った後、関数の処理を中断します(NaN については「非数」参照の事)。
この規則は、全ての数学関数で共通です。




NaN のテスト.

#include <stdio.h>
#include <fpieee.h>
#include <excpt.h>
#include "floatex.h"

char    *message[] = {
    "不正確結果", "アンダーフロー", "オーバーフロー",
    "ゼロ除算", "無効操作", 0
};

int __cdecl     fpieee_handler(_FPIEEE_RECORD *pieee)
{
    int     bits = *(int *)&pieee->Cause;
    char    **ppmes;

    ppmes = message;
    do{
        if (bits & 1) printf("%s ",*ppmes);
        bits >>= 1;
    }while(*++ppmes);

    printf("\n");

    return EXCEPTION_EXECUTE_HANDLER;
}

void __cdecl    main(void)
{
    FLOATEX         a,b,c,d,e;
    unsigned int    oldcw;

    floatex_clear87();
    oldcw = floatex_storecw();
    floatex_loadcw(FEX_PC_64 | FEX_RC_NEAR /* | FEX_MCW_EM */);

    __try{
        /*
          優先順は @ SNaN → QNaN 、A a → b → c となります。
          このプログラムの場合は b が適用されます。
        */

        floatex_qnan(1,a); /* 7fffc000000000000001 */
        floatex_snan(2,b); /* 7fff8000000000000002 */
        floatex_qnan(3,c); /* 7fffc000000000000003 */

        floatex_rotate(a,b,c,d,e); /* 座標回転関数 */
    }
    __except(
        _fpieee_flt(GetExceptionCode(),GetExceptionInformation(),
        fpieee_handler)){

        /*
          結果には SNaN が QNaN に変換されたものが返されます。
          この場合は "7fffc000000000000002" が表示されます。
        */

        printf("d : %04x",*(unsigned short *)(d + 8));
        printf("%016I64x\n",*(PUINT64)d);
        printf("e : %04x",*(unsigned short *)(e + 8));
        printf("%016I64x\n",*(PUINT64)e);
    }

    floatex_loadcw(oldcw);
}