mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
3.5 KiB
220 lines
3.5 KiB
|
|
#define IMCW_RC 0x00000003
|
|
#define IRC_CHOP 0x00000001
|
|
#define IRC_UP 0x00000002
|
|
#define IRC_DOWN 0x00000003
|
|
#define IRC_NEAR 0x00000000
|
|
#define fTrue 1
|
|
#define fFalse 0
|
|
|
|
unsigned int _statfp(void);
|
|
|
|
unsigned long rgconst[32] = { 0x80000000,
|
|
0xc0000000,
|
|
0xe0000000,
|
|
0xf0000000,
|
|
0xf8000000,
|
|
0xfc000000,
|
|
0xfe000000,
|
|
0xff000000,
|
|
|
|
0xff800000,
|
|
0xffc00000,
|
|
0xffe00000,
|
|
0xfff00000,
|
|
0xfff80000,
|
|
0xfffc0000,
|
|
0xfffe0000,
|
|
0xffff0000,
|
|
|
|
0xffff8000,
|
|
0xffffc000,
|
|
0xffffe000,
|
|
0xfffff000,
|
|
0xfffff800,
|
|
0xfffffc00,
|
|
0xfffffe00,
|
|
0xffffff00,
|
|
|
|
0xffffff80,
|
|
0xffffffc0,
|
|
0xffffffe0,
|
|
0xfffffff0,
|
|
0xfffffff8,
|
|
0xfffffffc,
|
|
0xfffffffe,
|
|
0xffffffff,
|
|
};
|
|
|
|
|
|
unsigned long rgconst2[32] = { 0x80000000,
|
|
0x40000000,
|
|
0x20000000,
|
|
0x10000000,
|
|
0x08000000,
|
|
0x04000000,
|
|
0x02000000,
|
|
0x01000000,
|
|
|
|
0x00800000,
|
|
0x00400000,
|
|
0x00200000,
|
|
0x00100000,
|
|
0x00080000,
|
|
0x00040000,
|
|
0x00020000,
|
|
0x00010000,
|
|
|
|
0x00008000,
|
|
0x00004000,
|
|
0x00002000,
|
|
0x00001000,
|
|
0x00000800,
|
|
0x00000400,
|
|
0x00000200,
|
|
0x00000100,
|
|
|
|
0x00000080,
|
|
0x00000040,
|
|
0x00000020,
|
|
0x00000010,
|
|
0x00000008,
|
|
0x00000004,
|
|
0x00000002,
|
|
0x00000001,
|
|
};
|
|
|
|
|
|
double _frnd(double x)
|
|
{
|
|
union {
|
|
unsigned long rg[2];
|
|
double db;
|
|
} _db;
|
|
short sign, exp;
|
|
int roundmode;
|
|
int fROUNDUP=fFalse;
|
|
|
|
_db.db = x;
|
|
|
|
roundmode = _statfp()&IMCW_RC;
|
|
|
|
sign = (short)((_db.rg[0] & 0x80000000)>>31);
|
|
exp = (short)((_db.rg[0] & 0x7ff00000)>>20);
|
|
|
|
if (sign && roundmode == IRC_DOWN)
|
|
{
|
|
roundmode = IRC_UP;
|
|
}
|
|
else if (sign && roundmode == IRC_UP)
|
|
{
|
|
roundmode = IRC_DOWN;
|
|
}
|
|
|
|
if (exp > 0 && exp < 2047)
|
|
{
|
|
//normalized
|
|
exp = exp -1023;
|
|
if (exp < 0)
|
|
{
|
|
if (roundmode == IRC_UP)
|
|
{
|
|
return (sign ? -1.0 : 1.0);
|
|
}
|
|
else if (roundmode == IRC_NEAR)
|
|
{
|
|
if (exp == -1)
|
|
{
|
|
return (sign ? -1.0 : 1.0);
|
|
}
|
|
}
|
|
return 0.0;
|
|
}
|
|
else if (exp >= 52)
|
|
{
|
|
return x;
|
|
}
|
|
else
|
|
{
|
|
if (exp > 20)
|
|
{
|
|
if (roundmode == IRC_UP)
|
|
{
|
|
if ((~rgconst[exp-21])&_db.rg[1])
|
|
{
|
|
fROUNDUP = fTrue;
|
|
}
|
|
}
|
|
else if (roundmode == IRC_NEAR)
|
|
{
|
|
if (rgconst2[exp-20]&_db.rg[1])
|
|
{
|
|
fROUNDUP=fTrue;
|
|
}
|
|
}
|
|
_db.rg[1] = rgconst[exp-21]&_db.rg[1];
|
|
}
|
|
else if (exp == 20)
|
|
{
|
|
if (roundmode == IRC_UP)
|
|
{
|
|
if (_db.rg[1])
|
|
{
|
|
fROUNDUP = fTrue;
|
|
}
|
|
}
|
|
else if (roundmode == IRC_NEAR)
|
|
{
|
|
if (rgconst2[0]&_db.rg[1])
|
|
{
|
|
fROUNDUP=fTrue;
|
|
}
|
|
}
|
|
_db.rg[1]=0;
|
|
}
|
|
else
|
|
{
|
|
if (roundmode == IRC_UP)
|
|
{
|
|
if ((~rgconst[exp+11])&_db.rg[0] || _db.rg[1])
|
|
{
|
|
fROUNDUP = fTrue;
|
|
}
|
|
}
|
|
else if (roundmode == IRC_NEAR)
|
|
{
|
|
if (rgconst2[exp+12]&_db.rg[0])
|
|
{
|
|
fROUNDUP=fTrue;
|
|
}
|
|
}
|
|
_db.rg[0]=rgconst[exp+11]&_db.rg[0];
|
|
_db.rg[1]=0;
|
|
}
|
|
|
|
if (fROUNDUP)
|
|
{
|
|
_db.db = _db.db + (sign ? -1.0 : 1.0);
|
|
}
|
|
|
|
return _db.db;
|
|
}
|
|
}
|
|
else if (exp == 0)
|
|
{
|
|
/* denormalized or zero*/
|
|
return x;
|
|
}
|
|
else if (exp == 2047)
|
|
{
|
|
/* inf or NaN */
|
|
return x;
|
|
}
|
|
else
|
|
{
|
|
/* should never get here */
|
|
;
|
|
}
|
|
|
|
}
|
|
|