● 関数リファレンス

シグナル型 NaN の作成

    PFLOATEX __stdcall  floatex_snan(UINT64 mantissa,PFLOATEX presult);

引数

引数名意味
mantissaSNaN の仮数部
presult結果を格納する FLOATEX型変数の先頭アドレス

戻り値

presult を返します。

説明

80 bit のシグナル型 NaN(SNaN)を作成します。
この関数は、主に例外を故意に発生させる目的で使用します。例外がマスクされていない状態で SNaN を FPU に演算させると、無効操作例外が発生します。

mantissa には SNaN の仮数部に設定する値を渡します。作成する SNaN の仮数部には (mantissa & 0x3fffffffffffffff) | 0x8000000000000000 がセットされます(mantissa の LSB から 62 ビット分だけが有効)。

この関数では、mantissa と 0x3fffffffffffffff の論理積が 0 の場合、小数部が 0 になる事を避けるため LSB に 1 をセットします。情報としてのゼロを付加したい場合は注意してください。

シグナル型 NaN は 指数部が 0x7fff 、仮数部は上位 2 ビットが 10b となります。それ以降は任意ですが、ゼロであってはなりません(0x7fff8000000000000000 は∞を表すため)。


この関数は、FPU を使用しません。


テスト.

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

/* 例外ハンドラ */
int __cdecl     fpieee_handler(_FPIEEE_RECORD *pieee)
{
    if (pieee->Cause.InvalidOperation &&        /* 無効操作例外 */
        pieee->Result.Format == _FpFormatFp80){ /* 80 bit 精度の場合 */

        char        buf[sizeof(UINT64)];

        memcpy(buf,&pieee->Result.Value.Fp80Value,sizeof(UINT64)-1);
        buf[sizeof(UINT64)-1] = 0;
        printf("%s\n",buf);

        return EXCEPTION_EXECUTE_HANDLER; /* __except ブロックへ移動 */
    }

    return EXCEPTION_CONTINUE_EXECUTION;
}

void __cdecl    main(void)
{
    FLOATEX         val;
    UINT64          mantissa;
    unsigned int    oldcw;

    floatex_clear87();

    oldcw = floatex_storecw();
    floatex_loadcw(FEX_PC_64 | FEX_RC_NEAR | (FEX_MCW_EM ^ FEX_EM_INVALID));

    __try{
        memcpy(&mantissa,"debug01",7);
        floatex_snan(mantissa,val);             /* SNaN の作成 */

        floatex_add(val,val);                   /* 例外を発生させる */
    }
    __except(_fpieee_flt(
                    GetExceptionCode(),
                    GetExceptionInformation(),
                    fpieee_handler)){
    }

    floatex_loadcw(oldcw);
}