コンパイラの中には、long double 型を 16 バイトでアラインしているものがあります(Intel C/C++等)。floatex.dll の処理に long double 型を混在させている場合、処理サイズを long double 型に合わせていると、FLOATEX 型変数の領域を超えてしまうので危険です。
long double 型のサイズが異なる事による不具合が疑われる場合は、コンパイラのマニュアルを参照するか、long double 型のサイズを直接調べてみてください。
#include <stdio.h>
void main(void)
{
printf("%u\n",sizeof(long double));
}
問題が発生しているプログラムと同じ設定でコンパイルすれば、より確実です。
サイズを調べた結果、long double 型が 10 バイトを超えている場合は、変数の下位側から 10 バイト分だけにアクセスするよう、処理を変更する必要があります。
対処としては、floatex_copy を用いて、処理として明確に 10 バイトだけ送る方法がありますが、FLOATEX_VALUE 共用体を使用する方法もあります。
例.
#include <stdio.h>
#include <math.h>
#define FEX_LONG_DOUBLE_SUPPORT
#include "floatex.h"
int main(void)
{
unsigned int oldcw;
FLOATEX_VALUE val;
char buf[32];
oldcw = floatex_storecw();
floatex_loadcw(FEX_MCW_EM | FEX_PC_64 | FEX_RC_NEAR);
val.ld_val = asinl(1.0L) * 2.0L;
floatex_ldstr_ldtoa(val.fex_val,buf);
printf("%s\n",buf);
floatex_ldstr_term();
floatex_loadcw(oldcw);
return 0;
}
double 型と FLOATEX 型は、直接代入を行う事ができません。64 bit の double 型 と 80 bit の FLOATEX 型では、サイズだけでなくデータのフォーマットも異なりますので、変換処理が必要になります。
FLOATEX a;
double b;
memcpy(a,&b,sizeof(b)); /* 変換できない */
通常は floatex_todouble 、floatex_doubleto を使用してください。
floatex.dll を扱う上での正規の方法.
FLOATEX a;
double b;
floatex_doubleto(b,a); /* a = b */
80 bit の long double 型に対応しているコンパイラの場合は、double 型 ・ long double 型の型変換を行えますので、FLOATEX 型の先頭アドレスを long double 型のポインタにキャストすれば、直に代入させる事ができます。
FLOATEX a;
double b;
*(long double *)a = b;
この方法は、移植性に難がある事に注意が必要です。16 バイトアラインの問題がある場合は、使用する事ができないかもしれません。
Microsoft の C/C++では、long double 型は double 型と同じ扱いになります(C規格上は問題ありません)。
floatex.dll を利用したプログラムにおいて、Microsoft 系のコンパイラを使用する場合は、型の問題を避けるために、long double 型を使用しない方がベターです。