After finishing off the Hardware-Software Interface course on Coursera offered by the University of Washington, one thing that I still felt I did not have a good grasp over was how floating point numbers are represented in binary. The course textbook, by Bryant and O'Hallaron, helped me get a much better understanding of how it is done under the IEEE 754 specification.
I then also wrote a small program, making use of Erlang's binary pattern matching capabilities, which converts a bit string into a float:
%% K - number of bits to representexp
%% N - number of bits to representfrac`. %% | s | exp(k bits) | frac(n bits) | make_float_converter(K, N) -> Bias = math:pow(2, K-1) - 1, Denom = math:pow(2, N), Max_exp = round(math:pow(2, K) - 1),
fun(<<S:1, Exp:K, Frac:N>>) -> case Exp of 0 -> E = 1 - Bias, % denormalized M = Frac / Denom, % 1/2 + 1/4 + .. + 1/(2^N) math:pow(-1, S) * M * math:pow(2, E); Max_exp -> case Frac of % special cases 0 -> case S of 0 -> pos_infinity; 1 -> neg_infinity end; _ -> nan % not a number end; _ -> E = Exp - Bias, % normalized M = 1 + (Frac / Denom), math:pow(-1, S) * M * math:pow(2, E) end end.
make_float_converter is a higher-order function that takes K- the number of bits you want to use to specify your exponent, and N- then number of bits you want to use to specify the fractional part of your float. It returns a
fun that pattern-matches a binary according to that specification, and then converts that binary representation into a float.
Example usage of the function:
F = ieee:make_float_converter(2,2).