///|
/// The base 2 logarithm of `x` (Float).
pub fn log2f(x : Float) -> Float {
let mut x = x
let ivln2hi : Float = 1.4428710938e+00 // 0x3fb8b000 */
let ivln2lo : Float = -1.7605285393e-04 // 0xb9389ad4 */
let lg1 : Float = 0.66666662693 // 0xaaaaaa.0p-24 */
let lg2 : Float = 0.40000972152 // 0xccce13.0p-25 */
let lg3 : Float = 0.28498786688 // 0x91e9ee.0p-25 */
let lg4 : Float = 0.24279078841 // 0xf89e26.0p-26 */
let mut ui : UInt = x.reinterpret_as_uint()
let mut ix = ui
let mut k = 0
if ix < 0x00800000 || ix >> 31 > 0 {
// x < 2**-126 */
if ix << 1 == 0 {
return -recipf(x * x)
} // log(+-0)=-inf */
if ix >> 31 > 0 {
return (x - x) / 0.0
} // log(-#) = NaN */
// subnormal number, scale up x */
k -= 25
x *= 0x1.0p25
ui = x.reinterpret_as_uint()
ix = ui
} else if ix >= 0x7f800000 {
return x
} else if ix == 0x3f800000 {
return 0.0
}
// reduce x into [sqrt(2)/2, sqrt(2)] */
ix += 0x3f800000U - 0x3f3504f3U
k += (ix >> 23).reinterpret_as_int() - 0x7f
ix = (ix & 0x007fffff) + 0x3f3504f3
ui = ix
x = Float::reinterpret_from_uint(ui)
let f = x - 1.0
let s = f / (f + 2.0)
let z = s * s
let w = z * z
let t1 = w * (lg2 + w * lg4)
let t2 = z * (lg1 + w * lg3)
let r = t2 + t1
let hfsq = f * f * 0.5
let hi = f - hfsq
let ui = hi.reinterpret_as_uint() & 0xfffff000
let hi = Float::reinterpret_from_uint(ui)
let lo = f - hi - hfsq + s * (hfsq + r)
(lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + Float::from_int(k)
}