ref: 8a3e8add6e0180565312d1079395ad39de4d9ce3
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)
}