Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

99 lines
2.3 KiB

/***
*hypot.c - hypotenuse and complex absolute value
*
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
*
*Purpose:
*
*Revision History:
* 08-15-91 GDP written
* 10-20-91 GDP removed inline assembly for calling sqrt
*
*******************************************************************************/
#include <math.h>
#include <trans.h>
static double _hypothlp(double x, double y, int who);
/***
*double _cabs(struct _complex z) - absolute value of a complex number
*
*Purpose:
*
*Entry:
*
*Exit:
*
*Exceptions:
*******************************************************************************/
double _cabs(struct _complex z)
{
return( _hypothlp(z.x, z.y, OP_CABS ) );
}
static double _hypothlp(double x, double y, int who)
{
double max;
double result, sum;
unsigned int savedcw;
int exp1, exp2, newexp;
/* save user fp control word */
savedcw = _maskfp();
/* check for infinity or NAN */
if (IS_D_SPECIAL(x) || IS_D_SPECIAL(y)){
if (IS_D_SNAN(x) || IS_D_SNAN(y)){
return _except2(FP_I,who,x,y,_d_snan2(x,y),savedcw);
}
if (IS_D_QNAN(x) || IS_D_QNAN(y)){
return _handle_qnan2(who,x,y,savedcw);
}
/* there is at least one infinite argument ... */
RETURN(savedcw,D_INF);
}
/* take the absolute values of x and y, compute the max, and then scale by
max to prevent over or underflowing */
if ( x < 0.0 )
x = - x;
if ( y < 0.0 )
y = - y;
max = ( ( y > x ) ? y : x );
if ( max == 0.0 )
RETURN(savedcw, 0.0 );
x /= max; //this may pollute the fp status word (underflow flag)
y /= max;
sum = x*x + y*y;
result = _decomp(sqrt(sum),&exp1) * _decomp(max,&exp2);
newexp = exp1 + exp2 + _get_exp(result);
// in case of overflow or underflow
// adjusting exp by IEEE_ADJUST will certainly
// bring the result in the representable range
if (newexp > MAXEXP) {
result = _set_exp(result, newexp - IEEE_ADJUST);
return _except2(FP_O | FP_P, who, x, y, result, savedcw);
}
if (newexp < MINEXP) {
result = _set_exp(result, newexp + IEEE_ADJUST);
return _except2(FP_U | FP_P, who, x, y, result, savedcw);
}
result = _set_exp(result, newexp);
// fix needed: P exception is raised even if the result is exact
RETURN_INEXACT2(who, x, y, result, savedcw);
}