Files
c3c/lib/std/math/math_nolibc/floor.c3
2025-10-25 15:55:25 +02:00

43 lines
985 B
Plaintext

module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH));
fn double _floor(double x) @weak @cname("floor") @nostrip
{
ulong ui = bitcast(x, ulong);
int e = (int)((ui >> 52) & 0x7ff);
if (e >= 0x3ff + 52 || x == 0) return x;
// y = int(x) - x, where int(x) is an integer neighbor of x
double y = ui >> 63 ? (x - TOINT) + TOINT - x : (x + TOINT) - TOINT - x;
// special case because of non-nearest rounding modes
if (e <= 0x3ff - 1)
{
force_eval_add(y, 0);
return ui >> 63 ? -1 : 0;
}
return y > 0 ? x + y - 1 : x + y;
}
fn float _floorf(float x) @weak @cname("floorf") @nostrip
{
uint u = bitcast(x, uint);
int e = (int)((u >> 23) & 0xff) - 0x7f;
switch
{
case e >= 23:
return x;
case e >= 0:
uint m = 0x007fffff >> e;
if (u & m == 0) return x;
force_eval_add(x, 0x1p120f);
if (u >> 31) u += m;
u &= ~m;
case u >> 31 == 0:
force_eval_add(x, 0x1p120f);
u = 0;
case (u << 1 != 0):
return -1;
}
return bitcast(u, float);
}