/* * round.h -- 丸めモードの指定 * 大石進一、精度保証付き数値計算、コロナ社 (2000) を参考にした */ #ifndef ROUND_ALREADY_INCLUDED #define ROUND_ALREADY_INCLUDED #if defined(__FreeBSD__) /* * FreeBSD は Linux と違って、浮動小数点数の標準精度が 53 bits なので * 大石先生の本にある CW の値を採用すると、矛盾が生じることに注意。 * ここでは FreeBSD で元から用意されている手順を採用する。 */ #include <machine/floatingpoint.h> #define Near() fpsetround(FP_RN) #define Up() fpsetround(FP_RP) #define Down() fpsetround(FP_RM) #elif defined(sparc) /* * これは大石先生の本にあるものを採用した。 */ /* #define QUICK */ #ifdef QUICK /* これは大石先生の本にも載っているが、Bias でもこうなっている */ static int _RoundNear = 0x00000000L; static int _RoundUp = 0x80000000L; static int _RoundDown = 0xC0000000L; #define Near() asm volatile("ld %0,%%fsr" : : "g" (_RoundNear)) #define Up() asm volatile("ld %0,%%fsr" : : "g" (_RoundUp)) #define Down() asm volatile("ld %0,%%fsr" : : "g" (_RoundDown)) #else #ifdef FALSE /* 大石先生の本にはこういうのが使えると書いてあるが使えない */ #include <floatingpoint.h> #define Near() ieee_flags("set", "direction", "nearest", &out) #define Up() ieee_flags("set", "direction", "positive", &out) #define Down() ieee_flags("set", "direction", "negative", &out) #endif /* これはオンライン・マニュアルから */ #include <ieeefp.h> #define Near() fpsetround(FP_RN) #define Up() fpsetround(FP_RP) #define Down() fpsetround(FP_RM) #endif #else /* FreeBSD でも Sparc でもなければ、とりあえず Bias まかせ */ /* Cygwin の場合は FreeBSD のときと同様で良いかな? */ #include <BiasInt.h> #define Near _BiasRoundNear #define Up _BiasRoundUp #define Down _BiasRoundDown #endif #endif