Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal

Idiom # 204: Return fraction and exponent of a real number

See programming-idioms.org:

Code

bits := f.cast_to_u64
fract_bits := f64.significand_bits.as_u64 - 1
bias := (u64 2 ** (f64.exponent_bits.as_u64 - 1) - 1)
mask := u64 2 ** f64.exponent_bits.as_u64 - 1
e := ((bits >> fract_bits) & mask).as_i32 - bias.as_i32 + 1
bits2 := bits & (~(mask << fract_bits))
bits3 := bits2 | ((bias - 1) << fract_bits)
if ((bits >> fract_bits) & mask) = 0 then
(bits3.cast_to_f64, e - 51)
else
(bits3.cast_to_f64, e)
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Runnable Example

ex204 is
frexp (f f64) tuple f64 i32 =>
bits := f.cast_to_u64
# bits is f in the following representation
# seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff
# where s = sign, e = exponent, f = fraction
fract_bits := f64.significand_bits.as_u64 - 1
# fract_bits is
# 0000000000000000000000000000000000000000000000000000000000110100
bias := (u64 2 ** (f64.exponent_bits.as_u64 - 1) - 1)
# bias is
# 0000000000000000000000000000000000000000000000000000001111111111
mask := u64 2 ** f64.exponent_bits.as_u64 - 1
# mask is
# 0000000000000000000000000000000000000000000000000000011111111111
# bits >> fract_bits will give us
# 0000000000000000000000000000000000000000000000000000seeeeeeeeeee
# AND this with mask
# 00000000000000000000000000000000000000000000000000000eeeeeeeeeee
e := ((bits >> fract_bits) & mask).as_i32 - bias.as_i32 + 1
# mask << fract_bits is
# 0111111111110000000000000000000000000000000000000000000000000000
# NOT this to get
# 1000000000001111111111111111111111111111111111111111111111111111
bits2 := bits & (~(mask << fract_bits))
# hence bits2 is
# s00000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff
# (bias - 1) << fract_bits is
# 0011111111100000000000000000000000000000000000000000000000000000
bits3 := bits2 | ((bias - 1) << fract_bits)
# therefore we have
# s01111111110ffffffffffffffffffffffffffffffffffffffffffffffffffff
# the last step is to "normalize" the exponent of the fraction
if ((bits >> fract_bits) & mask) = 0 then
(bits3.cast_to_f64, e - 51)
else
(bits3.cast_to_f64, e)
a f64 := 3.14
(b, c) := frexp a
say "{b} {c}"
d f64 := 5E-324
(exp, fract) := frexp d
say "{exp} {fract}"
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
last changed: 2024-07-01