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.
170 lines
3.4 KiB
170 lines
3.4 KiB
/***
|
|
*utill.c - utilities for fp transcendentals
|
|
*
|
|
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
|
|
*
|
|
*Purpose:
|
|
* _set_expl and _add_expl are as those defined in Cody & Waite
|
|
*
|
|
*Revision History:
|
|
* 08-15-91 GDP written
|
|
* 10-20-91 GDP removed _rint, unsafe_intrnd
|
|
* 02-05-92 GDP added _fpclass
|
|
* 03-27-92 GDP added _d_min
|
|
* 06-04-92 XY change to long double version
|
|
*
|
|
*******************************************************************************/
|
|
#include "transl.h"
|
|
#include "float.h"
|
|
|
|
/* define special values */
|
|
|
|
_ldbl _ld_inf = {0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //positive infinity
|
|
_ldbl _ld_ind = {0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //real indefinite
|
|
_ldbl _ld_max = {0x7f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //max long double
|
|
_ldbl _ld_min = {0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //min normalized double
|
|
|
|
|
|
/***
|
|
*int _fpclassl(long double x) - floating point class
|
|
*
|
|
*Purpose:
|
|
* Compute the floating point class of a number, according
|
|
* to the recommendations of the IEEE std. 754
|
|
*
|
|
*Entry:
|
|
*
|
|
*Exit:
|
|
*
|
|
*Exceptions:
|
|
* This function is never exceptional, even when the argument is SNAN
|
|
*
|
|
*******************************************************************************/
|
|
|
|
int _fpclassl(long double x)
|
|
{
|
|
int sign;
|
|
|
|
if (IS_LD_SPECIAL(x)){
|
|
switch (_sptypel(x)) {
|
|
case T_PINF:
|
|
return _FPCLASS_PINF;
|
|
case T_NINF:
|
|
return _FPCLASS_NINF;
|
|
case T_QNAN:
|
|
return _FPCLASS_QNAN;
|
|
default: //T_SNAN
|
|
return _FPCLASS_SNAN;
|
|
}
|
|
}
|
|
sign = (*LD_EXP(x)) & 0x8000;
|
|
if (x == 0.0)
|
|
return sign? _FPCLASS_NZ : _FPCLASS_PZ;
|
|
|
|
if (IS_LD_DENORM(x))
|
|
return sign? _FPCLASS_ND : _FPCLASS_PD;
|
|
|
|
return sign? _FPCLASS_NN : _FPCLASS_PN;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long double _set_expl(long double x, int exp)
|
|
/* does not check validity of exp */
|
|
{
|
|
long double retval;
|
|
int biased_exp;
|
|
retval = x;
|
|
biased_exp = exp + LD_BIASM1;
|
|
*LD_EXP(retval) = (unsigned short) (*LD_EXP(x) & 0x8000 | biased_exp );
|
|
return retval;
|
|
}
|
|
|
|
|
|
int _get_expl(long double x)
|
|
{
|
|
signed short exp;
|
|
exp = (signed short)(*LD_EXP(x) & 0x7fff);
|
|
exp -= LD_BIASM1; //unbias
|
|
return (int) exp;
|
|
}
|
|
|
|
|
|
long double _add_expl(long double x, int exp)
|
|
{
|
|
return _set_expl(x, INTEXPL(x)+exp);
|
|
}
|
|
|
|
|
|
long double _set_bexpl(long double x, int bexp)
|
|
/* does not check validity of bexp */
|
|
{
|
|
long double retval;
|
|
retval = x;
|
|
*LD_EXP(retval) = (unsigned short) (*LD_EXP(x) & 0x8000 | bexp);
|
|
return retval;
|
|
}
|
|
|
|
|
|
int _sptypel(long double x)
|
|
{
|
|
if (IS_LD_INF(x))
|
|
return T_PINF;
|
|
if (IS_LD_MINF(x))
|
|
return T_NINF;
|
|
if (IS_LD_QNAN(x))
|
|
return T_QNAN;
|
|
if (IS_LD_SNAN(x))
|
|
return T_SNAN;
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
*long double _decompl(long double x, int *expptr)
|
|
*
|
|
*Purpose:
|
|
* decompose a number to a normalized mantisa and exponent
|
|
*
|
|
*Entry:
|
|
*
|
|
*Exit:
|
|
*
|
|
*Exceptions:
|
|
*
|
|
*******************************************************************************/
|
|
|
|
long double _decompl(long double x, int *pexp)
|
|
{
|
|
int exp;
|
|
long double man;
|
|
|
|
if (x == 0) {
|
|
man = 0;
|
|
exp = 0;
|
|
}
|
|
else if (IS_LD_DENORM(x)) {
|
|
exp = 1-LD_BIASM1;
|
|
while(*LD_HI(x) & 0x8000 == 0) {
|
|
/* shift mantissa to the left until bit 17 is 1 */
|
|
(*LD_HI(x)) <<= 1;
|
|
if (*LD_LO(x) & 0x80000000)
|
|
(*LD_HI(x)) |= 0x1;
|
|
(*LD_LO(x)) <<= 1;
|
|
exp--;
|
|
}
|
|
man = _set_expl(x,0);
|
|
}
|
|
else {
|
|
man = _set_expl(x,0);
|
|
exp = INTEXPL(x);
|
|
}
|
|
|
|
*pexp = exp;
|
|
return man;
|
|
}
|