76 lines
4.2 KiB
C
76 lines
4.2 KiB
C
#ifndef VLIBC_TGMATH_H
|
|
#define VLIBC_TGMATH_H
|
|
|
|
/*
|
|
* vlibc — <tgmath.h>.
|
|
*
|
|
* Type-generic math (C23 7.25). Each macro inspects the type of its
|
|
* controlling expression and dispatches to the matching precision of the
|
|
* real <math.h> function: a float argument selects the `...f` variant, a
|
|
* long double argument the `...l` variant, and everything else (double,
|
|
* any integer type, and the _Complex types, whose imaginary part is
|
|
* dropped by the usual argument conversion) the unsuffixed double
|
|
* variant. The controlling expression is the first floating argument, so
|
|
* the two-argument forms dispatch on x and require y to be convertible to
|
|
* x's type.
|
|
*
|
|
* This header is ISO C core and is present in every profile. The
|
|
* classification macros (fpclassify/isnan/isinf/isfinite/isnormal/signbit)
|
|
* need no dispatch of their own — <math.h> already defines them over
|
|
* GCC's type-generic builtins, so including <math.h> below makes them
|
|
* work unchanged for every real and complex type.
|
|
*/
|
|
|
|
#include <math.h>
|
|
|
|
/* fabs */
|
|
#define fabs(x) _Generic((x), float: fabsf, long double: fabsl, default: fabs)(x)
|
|
|
|
/* copysign */
|
|
#define copysign(x, y) \
|
|
_Generic((x), float: copysignf, long double: copysignl, default: copysign)(x, y)
|
|
|
|
/* rounding toward zero / ±Inf / current mode (floor, ceil, trunc, round,
|
|
* rint, nearbyint) */
|
|
#define floor(x) _Generic((x), float: floorf, long double: floorl, default: floor)(x)
|
|
#define ceil(x) _Generic((x), float: ceilf, long double: ceill, default: ceil)(x)
|
|
#define trunc(x) _Generic((x), float: truncf, long double: truncl, default: trunc)(x)
|
|
#define round(x) _Generic((x), float: roundf, long double: roundl, default: round)(x)
|
|
#define rint(x) _Generic((x), float: rintf, long double: rintl, default: rint)(x)
|
|
#define nearbyint(x) \
|
|
_Generic((x), float: nearbyintf, long double: nearbyintl, default: nearbyint)(x)
|
|
|
|
/* integer-returning rounding (lrint, llrint, lround, llround) */
|
|
#define lrint(x) _Generic((x), float: lrintf, long double: lrintl, default: lrint)(x)
|
|
#define llrint(x) _Generic((x), float: llrintf, long double: llrintl, default: llrint)(x)
|
|
#define lround(x) _Generic((x), float: lroundf, long double: lroundl, default: lround)(x)
|
|
#define llround(x) _Generic((x), float: llroundf, long double: llroundl, default: llround)(x)
|
|
|
|
/* fraction/exponent splitting (frexp, modf) and exponent scaling (ldexp,
|
|
* scalbn, scalbln): the second argument is an int/long or a pointer to
|
|
* the first argument's type and follows x's precision automatically */
|
|
#define frexp(x, e) _Generic((x), float: frexpf, long double: frexpl, default: frexp)(x, e)
|
|
#define modf(x, i) _Generic((x), float: modff, long double: modfl, default: modf)(x, i)
|
|
#define ldexp(x, n) _Generic((x), float: ldexpf, long double: ldexpl, default: ldexp)(x, n)
|
|
#define scalbn(x, n) _Generic((x), float: scalbnf, long double: scalbnl, default: scalbn)(x, n)
|
|
#define scalbln(x, n) _Generic((x), float: scalblnf, long double: scalblnl, default: scalbln)(x, n)
|
|
|
|
/* minimum/maximum/difference */
|
|
#define fmin(x, y) _Generic((x), float: fminf, long double: fminl, default: fmin)(x, y)
|
|
#define fmax(x, y) _Generic((x), float: fmaxf, long double: fmaxl, default: fmax)(x, y)
|
|
#define fdim(x, y) _Generic((x), float: fdimf, long double: fdiml, default: fdim)(x, y)
|
|
|
|
/* remainder (fmod, remainder, remquo: the trailing int* follows x's
|
|
* precision) */
|
|
#define fmod(x, y) _Generic((x), float: fmodf, long double: fmodl, default: fmod)(x, y)
|
|
#define remainder(x, y) \
|
|
_Generic((x), float: remainderf, long double: remainderl, default: remainder)(x, y)
|
|
#define remquo(x, y, q) \
|
|
_Generic((x), float: remquof, long double: remquol, default: remquo)(x, y, q)
|
|
|
|
/* exponent reading (ilogb returns int, logb returns x's precision) */
|
|
#define ilogb(x) _Generic((x), float: ilogbf, long double: ilogbl, default: ilogb)(x)
|
|
#define logb(x) _Generic((x), float: logbf, long double: logbl, default: logb)(x)
|
|
|
|
#endif /* VLIBC_TGMATH_H */
|