feat(math): abs/round/trunc/frexp/ldexp/scalbn/copysign/fmin/fmax/fmod

This commit is contained in:
2026-09-06 01:07:31 -04:00
parent c4c64a4eb5
commit b731a02db4
30 changed files with 5912 additions and 7 deletions
+64 -7
View File
@@ -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 */