module std::math::nolibc @if(env::NO_LIBC || $feature(C3_MATH)); fn double ldexp(double x, int exp) @cname("ldexp") { uint hx = x.high_word(); int hexp = (int)((hx & 0x7ff00000) >> 20); if (hexp == 0x7ff) return x; if (hexp == 0) { // subnormal number handling x *= 0x1p64; hx = x.high_word(); hexp = (int)((hx & 0x7ff00000) >> 20) - 64; } // new exponent calculation hexp += exp; if (hexp > 0x7fe) return x * double.inf; if (hexp < 1) { x *= 0x1p-1022; hexp += 1022; if (hexp < 1) x *= 0x1p-1022; return x; } // set new exponent hx = ((ulong)hx & 0x800fffff) | ((ulong)hexp << 20); { ulong rep = ((ulong)hx << 32) | x.low_word(); return bitcast(rep, double); } } fn float ldexpf(float x, int exp) @cname("ldexpf") { uint ix = x.word(); int hexp = (int)((ix & 0x7f800000) >> 23); if (hexp == 0xff) return x; if (hexp == 0) { // subnormal number handling x *= 0x1p64f; ix = x.word(); hexp = (int)((ix & 0x7f800000) >> 23) - 64; } // new exponent calculation hexp += exp; if (hexp > 0xfe) return x * float.inf; if (hexp < 1) { x *= 0x1p-126f; hexp += 126; if (hexp < 1) x *= 0x1p-126f; return x; } // set new exponent ix = (ix & 0x807fffff) | (hexp << 23); return bitcast(ix, float); }