def double.f32bits

bendonnect-rpc@0.1.0.0 · src/pb.bend:336

import bendonnect-rpc@0.1.0.0/src/pb.bend as Pb
import Base
import bend-kit-protobuf@0.1.0.0/protobuf.bend as Pb

336# IEEE binary64 bits -> binary32 bits, round to nearest even (overflow -> infinity, tiny -> zero).
337def double.f32bits(w: Pb.Word64) -> U32:
338  Pb.Word64{+h, +l} = w
339  +s = ((h >> 31n) << 31n : U32)
340  +e = ((h >> 20n) .&. 2047 : U32)
341  +fh = (h .&. 1048575 : U32)
342  +m23 = ((fh << 3n) .|. (l >> 29n) : U32)
343  +rem = (l .&. 536870911 : U32)
344  +up = U32.is_gt(rem, 268435456) || (U32.is_eq(rem, 268435456) && U32.is_eq((m23 .&. 1 : U32), 1))
345  +normal = (((e - 896) << 23n) + m23 + Bool.to_u32(up) : U32)
346  +special = Bool.pick(U32, U32.is_zero(fh) && U32.is_zero(l), 2139095040, (2143289344 .|. m23 : U32))
347  +k = (926 - e : U32)
348  +sig = {Pb.Word64{(fh .|. 1048576 : U32), l} : Pb.Word64}
349  +mm = word64.lo(word64.shr(sig, k))
350  +t = word64.shl(sig, (64 - k : U32))
351  +th = word64.hi(t)
352  +tl = word64.lo(t)
353  +gt = U32.is_gt(th, 2147483648) || (U32.is_eq(th, 2147483648) && U32.is_ne(tl, 0))
354  +eq = U32.is_eq(th, 2147483648) && U32.is_zero(tl)
355  +up2 = gt || (eq && U32.is_eq((mm .&. 1 : U32), 1))
356  +subn = (mm + Bool.to_u32(up2) : U32)
357  (s .|. Bool.pick(U32, U32.is_eq(e, 2047), special,
358        Bool.pick(U32, U32.is_ge(e, 1151), 2139095040,
359        Bool.pick(U32, U32.is_ge(e, 897), normal,
360        Bool.pick(U32, U32.is_ge(e, 873), subn, 0))))
361    : U32)

Uses (21)

Used by (1)