(* Copyright 2021-2024 Sebastian Lederer. See the file LICENSE.md for details *)
function encodefloat32(r:real):integer;
var	intpart:real;
	fract: real;
	exponent:integer;
	sign:integer;
	i:integer;
	digit, bitpos:integer;
	intlength,fractlength:integer;
	intbin:integer;
	fractbin:integer;
	floatbin:integer;
begin
	intbin := 0; fractbin := 0; floatbin := 0;

	if r<0 then
	begin
		r := abs(r);
		sign := 1;
	end
	else
		sign := 0;

	if r = 0.0 then
	begin
		intpart := 0.0;
		fract := 0.0;
		intlength := 0;
		fractlength := 0;
		intbin := 0;
		fractbin := 0;
		floatbin := 0;
	end
	else
	begin
		intpart := r;
		fract := frac(r);
		exponent := floor(log2(intpart));

		intlength := exponent+1;
		fractlength :=  wordbits - intlength - Float32ExpBits - 1;
	end;
		(* FIXME: log2 gives division by zero on zero arg *)


	(* process bits before the point *)
	for i := 1 to intlength do
	begin
		(* digit := round(intpart mod 2.0); *)
		(* calculate real remainder in a portable way *)
		digit := floor(intpart - 2 * Int(intpart / 2));

		(* if we used up all the bits in the fraction part of
			the float32 encoding, shift everything right
			and put bit at the top *)
		if i > Float32FractBits then
		begin
			bitpos := Float32FractBits-1;
			intbin := intbin shr 1;
		end
		else
			bitpos := i - 1;

		if digit > 0 then intbin := intbin  + (1 << bitpos);

		intpart := intpart / 2.0;
	end;

    (* limit the integer bits *)
	if intlength > Float32FractBits then intlength := Float32FractBits;

	(* process bits after the point, if we have any bits left *)
	if fractlength > 0 then
	begin	
		for i := 1 to fractlength do
		begin
			fract := fract * 2;
			digit := trunc(fract) and 1;
			fractbin := (fractbin shl 1) + digit;
		end;

	end;

	floatbin := (intbin << (Float32FractBits - intlength)) + fractbin;

	if floatbin = 0 then (* if mantissa is zero, return a clean zero value *)
		encodefloat32 := 0
	else
	begin
		exponent := exponent + Float32ExpBias;
		if (exponent > Float32ExpMax) or (exponent < 0) then
			errorExit2('float exponent overflow','');
		encodefloat32 := (sign shl (wordBits-1)) + (floatbin << Float32ExpBits) + exponent;
	end;
end;
