50 lines
1.2 KiB
C
50 lines
1.2 KiB
C
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <math.h>
|
|
|
|
/*
|
|
* The nearest integral value to x in the current rounding direction,
|
|
* returned as long (C23 7.12.9.7), all three precisions. A result
|
|
* outside the range of long is a range error whose return value is
|
|
* unspecified, so the header declares no const attribute; the test
|
|
* corpus keeps |x| < 2^62 where every result is exact.
|
|
*
|
|
* GCC never folds the __builtin_lrint* forms on this target (external
|
|
* lrint@PLT calls at every optimization level), so lrint is built as
|
|
* rint-then-convert: __builtin_rint* folds to the in-line round-to-
|
|
* nearest-even sequence (see rint.c), producing an exact integral value,
|
|
* and the cast to long is then exact no matter which conversion
|
|
* instruction GCC emits. The rint step honors the MXCSR/x87 rounding
|
|
* mode, the only reachable one being the default round-to-nearest-even
|
|
* (no <fenv.h> exists in vlibc yet).
|
|
*/
|
|
|
|
/*
|
|
* As lrint, for a float argument.
|
|
*/
|
|
long
|
|
lrintf(float x)
|
|
{
|
|
return (long)__builtin_rintf(x);
|
|
}
|
|
|
|
/*
|
|
* As lrint, for a double argument.
|
|
*/
|
|
long
|
|
lrint(double x)
|
|
{
|
|
return (long)__builtin_rint(x);
|
|
}
|
|
|
|
/*
|
|
* As lrint, for a long double argument.
|
|
*/
|
|
long
|
|
lrintl(long double x)
|
|
{
|
|
return (long)__builtin_rintl(x);
|
|
}
|