#ifndef VLIBC_TGMATH_H #define VLIBC_TGMATH_H /* * vlibc — . * * Type-generic math (C23 7.25). Each macro inspects the type of its * controlling expression and dispatches to the matching precision of the * real 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 — already defines them over * GCC's type-generic builtins, so including below makes them * work unchanged for every real and complex type. */ #include /* 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 */