ref: 6fb7d34b848c598e6398f960dc0a7e240e09a6f5
dir: /lib/math/fpmath-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) ;; pkglocal const trunc32 = {f : flt32 var u : uint32 = std.flt32bits(f) var e : uint32 = (((u >> 23) & 0xff) : uint32) - 127 var e_lt_zero : uint32 = ((e >> 31) : uint32) & 0x1 var e_ge_zero : uint32 = 1 - e_lt_zero var e_ge_23 : uint32 = 1 - ((e - 23) >> 31) /* The significand 1 . m1 m2 ... m23 needs to be truncated, which corresponds to zeroing all mi bits where i is beyond the exponent e (they are the actual sub-integer portion). */ var m : uint32 = ~(((1 << 23) - 1) >> e) m |= (-1 : uint32) * e_ge_23 var v_ge_zero : uint32 = (u & m) * e_ge_zero /* On the other hand, if the exponent is < 0, "23 - e" is garbage, and we should just return +/- zero */ var v_lt_zero : uint32 = (u & (1 << 31)) * e_lt_zero /* Try to save a branch */ var v : uint32 = v_ge_zero + v_lt_zero -> std.flt32frombits(v) } pkglocal const floor32 = {f : flt32 var u : uint32 = std.flt32bits(f) var e : int32 = (((u >> 23) & 0xff) : int32) - 127 var shift_e : uint32 = (e : uint32) /* Many special cases */ if e >= 23 || u == 0x80000000 -> f elif (e < 0) && (u & (1 << 31) != 0) -> -1.0 elif e < 0 -> 0.0 ;; if u & (1 << 31) != 0 var fractional_mask : uint32 = (((1 << 23) - 1) >> shift_e) var v : uint32 = u & ~fractional_mask if (u & fractional_mask) != 0 v += ((1 << 23) >> shift_e) ;; -> std.flt32frombits(v) ;; var m : uint32 = ~(((1 << 23) - 1) >> shift_e) var v : uint32 = u & m -> std.flt32frombits(v) } pkglocal const ceil32 = {f; var u : uint32 = std.flt32bits(f) var e : int32 = (((u >> 23) & 0xff) : int32) - 127 var shift_e : uint32 = (e : uint32) if e >= 23 || u == 0x0 -> f elif (e < 0) && (u & (1 << 31) == 0) -> 1.0 elif e < 0 -> -0.0 ;; if u & (1 << 31) == 0 var fractional_mask : uint32 = (((1 << 23) - 1) >> shift_e) var v : uint32 = u & ~fractional_mask if (u & fractional_mask) != 0 v += ((1 << 23) >> shift_e) ;; -> std.flt32frombits(v) ;; var m : uint32 = ~(((1 << 23) - 1) >> shift_e) var v : uint32 = u & m -> std.flt32frombits(v) } pkglocal const trunc64 = {f : flt64 var u : uint64 = std.flt64bits(f) var e : uint64 = (((u >> 52) & 0x7ff) : uint64) - 1023 var e_lt_zero : uint64 = ((e >> 63) : uint64) & 0x1 var e_ge_zero : uint64 = 1 - e_lt_zero var e_ge_52 : uint64 = 1 - ((e - 52) >> 63) var m : uint64 = ~(((1 << 52) - 1) >> e) m |= (-1 : uint64) * e_ge_52 var v_ge_zero : uint64 = (u & m) * e_ge_zero var v_lt_zero : uint64 = (u & (1 << 63)) * e_lt_zero var v : uint64 = v_ge_zero + v_lt_zero -> std.flt64frombits(v) } pkglocal const floor64 = {f : flt64 var u : uint64 = std.flt64bits(f) var e : int64 = (((u >> 52) & 0x7ff) : int64) - 1023 var shift_e : uint64 = (e : uint64) if e >= 52 || u == 0x8000000000000000ul -> f elif (e < 0) && (u & (1 << 63) != 0) -> -1.0 elif e < 0 -> 0.0 ;; if u & (1 << 63) != 0 var fractional_mask : uint64 = (((1 << 52) - 1) >> shift_e) var v : uint64 = u & ~fractional_mask if (u & fractional_mask) != 0 v += ((1 << 52) >> shift_e) ;; -> std.flt64frombits(v) ;; var m : uint64 = ~(((1 << 52) - 1) >> shift_e) var v : uint64 = u & m -> std.flt64frombits(v) } pkglocal const ceil64 = {f; var u : uint64 = std.flt64bits(f) var e : int64 = (((u >> 52) & 0x7ff) : int64) - 1023 var shift_e : uint64 = (e : uint64) if e >= 52 || u == 0x0ul -> f elif (e < 0) && (u & (1 << 63) == 0) -> 1.0 elif e < 0 -> -0.0 ;; if u & (1 << 63) == 0 var fractional_mask : uint64 = (((1 << 52) - 1) >> shift_e) var v : uint64 = u & ~fractional_mask if (u & fractional_mask) != 0 v += ((1 << 52) >> shift_e) ;; -> std.flt64frombits(v) ;; var m : uint64 = ~(((1 << 52) - 1) >> shift_e) var v : uint64 = u & m -> std.flt64frombits(v) }