2021-10-11 18:20:23 -03:00

98 lines
2.0 KiB
C

#ifndef lint
static char sccsid[] = "@(#)rint.c 1.1 92/07/30 SMI";
#endif
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*/
/*
* aint(x) return x chopped to integral value
* anint(x) return sign(x)*(|x|+0.5) chopped to integral value
* ceil(x) return the biggest integral value below x
* floor(x) return the least integral value above x
* irint(x) return rint(x) in integer format
* nint(x) return anint(x) in integer format
* rint(x) return x rounded to integral according to the rounding direction
*
* NOTE: aint(x), anint(x), ceil(x), floor(x), and rint(x) return result
* with the same sign as x's, including 0.0.
*/
#include <math.h>
#include "libm.h"
static double zero = 0.0;
double aint(x)
double x ;
{
double t,w;
w = fabs(x);
t = rint(w);
if (x!=x||t<=w) return copysign(t,x); /* NaN or already aint(|x|) */
else return copysign(t-1.0,x); /* |t|>|x| case */
}
double anint(x)
double x ;
{
double t,w,z;
w = fabs(x);
t = rint(w);
if (x!=x||t==w) return copysign(t,x);
z = t - w;
if(z > 0.5) t -= 1.0; else
if(z <= -0.5) t += 1.0;
return copysign(t,x);
}
double ceil(x)
double x ;
{
double t;
t = rint(x);
if (x!=x||t>=x) return t; /* NaN or already ceil(x) */
else return copysign(t+1.0,x); /* t < x case: return t+1 */
}
double floor(x)
double x ;
{
double t;
t = rint(x);
if (x!=x||t<=x) return t; /* NaN or already floor(x) */
else return copysign(t-1.0,x); /* x < t case: return t-1 */
}
int irint(x)
double x;
{
return (int) rint(x);
}
int nint(x)
double x;
{
return (int) anint(x);
}
double rint(x)
double x;
{
enum fp_precision_type _swapRP(),rp;
double t,w;
char *out;
t = fabs(x);
if (x!=x||fabs(x)>=two52) return x-zero;/* NaN or already an integer */
t = copysign(two52,x);
rp = _swapRP(fp_double);/* make sure precision is double */
w = x+t; /* x+sign(x)*2**52 rounded to integer */
_swapRP(rp); /* restore precision mode */
if(w==t) return copysign(zero,x); /* x rounded to zero */
else return w - t;
}