* Use "math.h" instead of <math.h>.

* Use bit twiddling.  This requires inclusion of math_private.h
  and inclusion of float.h in s_roundl.c.  Raise invalid exception.
* Use literal integer constants where possible.  Let the compiler
  do the appropriate conversion.
* In s_roundf.c, use an F suffix on float constants instead of
  promoting float to double and then converting the result back
  to float. In s_roundl.c, use an L suffix.
* In s_roundl.c, use the ENTERI and RETURNI macros.  This requires
  the inclusion of fpmath.h and on __i386__ class hardware ieeefp.h.

Reviewed by:	bde
This commit is contained in:
Steve Kargl 2013-11-06 23:44:52 +00:00
parent ded71d6788
commit db89cf8efb
3 changed files with 41 additions and 24 deletions

View File

@ -27,25 +27,28 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <math.h>
#include "math.h"
#include "math_private.h"
double
round(double x)
{
double t;
uint32_t hx;
if (!isfinite(x))
return (x);
GET_HIGH_WORD(hx, x);
if ((hx & 0x7fffffff) == 0x7ff00000)
return (x + x);
if (x >= 0.0) {
if (!(hx & 0x80000000)) {
t = floor(x);
if (t - x <= -0.5)
t += 1.0;
t += 1;
return (t);
} else {
t = floor(-x);
if (t + x <= -0.5)
t += 1.0;
t += 1;
return (-t);
}
}

View File

@ -27,25 +27,28 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <math.h>
#include "math.h"
#include "math_private.h"
float
roundf(float x)
{
float t;
uint32_t hx;
if (!isfinite(x))
return (x);
GET_FLOAT_WORD(hx, x);
if ((hx & 0x7fffffff) == 0x7f800000)
return (x + x);
if (x >= 0.0) {
if (!(hx & 0x80000000)) {
t = floorf(x);
if (t - x <= -0.5)
t += 1.0;
if (t - x <= -0.5F)
t += 1;
return (t);
} else {
t = floorf(-x);
if (t + x <= -0.5)
t += 1.0;
if (t + x <= -0.5F)
t += 1;
return (-t);
}
}

View File

@ -27,25 +27,36 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <math.h>
#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
#endif
#include "fpmath.h"
#include "math.h"
#include "math_private.h"
long double
roundl(long double x)
{
long double t;
uint16_t hx;
if (!isfinite(x))
return (x);
GET_LDBL_EXPSIGN(hx, x);
if ((hx & 0x7fff) == 0x7fff)
return (x + x);
if (x >= 0.0) {
ENTERI();
if (!(hx & 0x8000)) {
t = floorl(x);
if (t - x <= -0.5)
t += 1.0;
return (t);
if (t - x <= -0.5L)
t += 1;
RETURNI(t);
} else {
t = floorl(-x);
if (t + x <= -0.5)
t += 1.0;
return (-t);
if (t + x <= -0.5L)
t += 1;
RETURNI(-t);
}
}