89 lines
1.8 KiB
C
89 lines
1.8 KiB
C
/*++
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
modf.c
|
|
|
|
Abstract:
|
|
|
|
modf() function
|
|
|
|
Author:
|
|
|
|
|
|
|
|
Revision History:
|
|
|
|
29-sept-1999 ATM Shafiqul Khalid [askhalid] copied from rtl library.
|
|
--*/
|
|
|
|
#include <math.h>
|
|
#include <trans.h>
|
|
#include <float.h>
|
|
|
|
extern double _frnd(double);
|
|
extern double _copysign (double x, double y);
|
|
|
|
/***
|
|
*double modf(double x, double *intptr)
|
|
*
|
|
*Purpose:
|
|
* Split x into fractional and integer part
|
|
* The signed fractional portion is returned
|
|
* The integer portion is stored as a floating point value at intptr
|
|
*
|
|
*Entry:
|
|
*
|
|
*Exit:
|
|
*
|
|
*Exceptions:
|
|
* I
|
|
*******************************************************************************/
|
|
static unsigned int newcw = (ICW & ~IMCW_RC) | (IRC_CHOP & IMCW_RC);
|
|
|
|
double modf(double x, double *intptr)
|
|
{
|
|
unsigned int savedcw;
|
|
double result,intpart;
|
|
|
|
/* save user fp control word */
|
|
savedcw = _ctrlfp(0, 0); /* get old control word */
|
|
_ctrlfp(newcw,IMCW); /* round towards 0 */
|
|
|
|
/* check for infinity or NAN */
|
|
if (IS_D_SPECIAL(x)){
|
|
*intptr = QNAN_MODF;
|
|
switch (_sptype(x)) {
|
|
case T_PINF:
|
|
case T_NINF:
|
|
*intptr = x;
|
|
result = _copysign(0, x);
|
|
RETURN(savedcw,result);
|
|
case T_QNAN:
|
|
*intptr = x;
|
|
return _handle_qnan1(OP_MODF, x, savedcw);
|
|
default: //T_SNAN
|
|
result = _s2qnan(x);
|
|
*intptr = result;
|
|
return _except1(FP_I, OP_MODF, x, result, savedcw);
|
|
}
|
|
}
|
|
|
|
if (x == 0.0) {
|
|
*intptr = x;
|
|
result = x;
|
|
}
|
|
|
|
else {
|
|
intpart = _frnd(x); //fix needed: this may set the P exception flag
|
|
//and pollute the fp status word
|
|
|
|
*intptr = intpart;
|
|
result = x - intpart;
|
|
}
|
|
|
|
RETURN(savedcw,result);
|
|
}
|