ref: 8c96aa052a1c592f008660729384c9a44988d248
dir: /lib/math/trunc-impl.myr/
use std pkg math = pkglocal const trunc32 : (f : flt32 -> flt32) pkglocal const floor32 : (f : flt32 -> flt32) pkglocal const ceil32 : (f : flt32 -> flt32) pkglocal const trunc64 : (f : flt64 -> flt64) pkglocal const floor64 : (f : flt64 -> flt64) pkglocal const ceil64 : (f : flt64 -> flt64) ;; const Flt32NegMask : uint32 = (1 << 31) const Flt32SigMask : uint32 = (1 << 23) - 1 const Flt64NegMask : uint64 = (1 << 63) const Flt64SigMask : uint64 = (1 << 52) - 1 pkglocal const floor32 = {f : flt32 var n, e, s (n, e, s) = std.flt32explode(f) /* Many special cases */ if e >= 23 || f == -0.0 -> f elif e < 0 if n -> -1.0 else -> 0.0 ;; ;; if n var fractional_mask = Flt32SigMask >> (e : uint32) if s & fractional_mask == 0 -> f else /* Turns out the packing of exp and sig is useful */ var u : uint32 = std.flt32bits(f) & ~fractional_mask u += ((1 << 23) >> (e : uint32)) -> std.flt32frombits(u) ;; ;; var m : uint32 = (Flt32SigMask >> (e : uint32)) -> std.flt32assem(n, e, s & ~m) } pkglocal const trunc32 = {f : flt32 if std.flt32bits(f) & Flt32NegMask != 0 -> -floor32(-f) else -> floor32(f) ;; } pkglocal const ceil32 = {f : flt32 -> -floor32(-f) } pkglocal const floor64 = {f : flt64 var n, e, s (n, e, s) = std.flt64explode(f) /* Many special cases */ if e >= 52 || f == -0.0 -> f elif e < 0 if n -> -1.0 else -> 0.0 ;; ;; if n var fractional_mask = Flt64SigMask >> (e : uint64) if s & fractional_mask == 0 -> f else /* Turns out the packing of exp and sig is useful */ var u : uint64 = std.flt64bits(f) & ~fractional_mask u += ((1 << 52) >> (e : uint64)) -> std.flt64frombits(u) ;; ;; var m : uint64 = (Flt64SigMask >> (e : uint64)) -> std.flt64assem(n, e, s & ~m) } pkglocal const trunc64 = {f : flt64 if std.flt64bits(f) & Flt64NegMask != 0 -> -floor64(-f) else -> floor64(f) ;; } pkglocal const ceil64 = {f : flt64 -> -floor64(-f) }