feat(math): abs/round/trunc/frexp/ldexp/scalbn/copysign/fmin/fmax/fmod
This commit is contained in:
+64
-7
@@ -4,15 +4,72 @@
|
||||
/*
|
||||
* vlibc — <tgmath.h>.
|
||||
*
|
||||
* Type-generic math. STUB: the type-generic dispatch over <math.h> is
|
||||
* IMPLEMENTED by the first math todo (#39), not here. This stub exists so
|
||||
* that including <tgmath.h> alongside the other headers compiles cleanly
|
||||
* today; it deliberately defines no type-generic macros until #39 lands
|
||||
* the <math.h> function inventory it dispatches to.
|
||||
* 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.
|
||||
* 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 <vlibc/features.h>
|
||||
#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 */
|
||||
|
||||
Reference in New Issue
Block a user