@@ -148,6 +148,67 @@ signed integer, so that `abs(typemin(x)) == typemin(x) < 0`, in which case the r
148148uabs (x:: Integer ) = abs (x)
149149uabs (x:: BitSigned ) = unsigned (abs (x))
150150
151+ function float_representation (
152+ :: Type{F} ,
153+ signbit:: Bool , exponent_field:: Integer , mantissa_field:: Integer ,
154+ ) where {F<: IEEEFloat }
155+ T = uinttype (F)
156+ sign_and_exp = (T (signbit) << exponent_bits (F)) | T (exponent_field)
157+ ret = (sign_and_exp << significand_bits (F)) | T (mantissa_field)
158+ ret:: T
159+ end
160+
161+ float_representation_of_infinity (:: Type{F} , signbit:: Bool ) where {F<: IEEEFloat } =
162+ float_representation (F, signbit, exponent_raw_max (F), false )
163+
164+ float_representation_of_zero (:: Type{F} , signbit:: Bool ) where {F<: IEEEFloat } =
165+ float_representation (F, signbit, false , false )
166+
167+ function float_representation_from_components (
168+ :: Type{F} ,
169+ sign:: Real , exp:: Integer , mantissa:: Integer ,
170+ ) where {F<: IEEEFloat }
171+ T = uinttype (F)
172+ sb = signbit (sign)
173+
174+ iszero (sign) && return float_representation_of_zero (F, sb)
175+
176+ normalized_exp = exp + significand_bits (F)
177+
178+ if exponent_max (F) < normalized_exp
179+ # overflow (infinity)
180+ float_representation_of_infinity (F, sb)
181+ elseif normalized_exp < true - exponent_bias (F)
182+ # underflow (subnormal or zero)
183+ ed = true - exponent_bias (F) - normalized_exp
184+ float_representation (F, sb, false , mantissa >> ed)
185+ else
186+ # normal: `true - exponent_bias(F) ≤ normalized_exp ≤ exponent_max(F)`
187+ mantissa_field = T (mantissa) & significand_mask (F) # clear the leading set bit
188+ e = normalized_exp + exponent_bias (F)
189+ float_representation (F, sb, e, mantissa_field)
190+ end
191+ end
192+
193+ float_from_components (
194+ :: Type{F} ,
195+ sign:: Real , exp:: Integer , mantissa:: Integer ,
196+ ) where {F<: IEEEFloat } =
197+ reinterpret (F, float_representation_from_components (F, sign, exp, mantissa))
198+
199+ # The input parameters represent the number `sign * 2^exp * mantissa`,
200+ # let's call it `n`. The sign is expected to be an integer between `-1`
201+ # and `1`, and the mantissa is expected to be as wide as the mantissa
202+ # of the floating-point type `F`, not counting the leading bit. Let's
203+ # call the number `x`.
204+ #
205+ # Returns the same value as `ldexp(sign * F(mantissa), exp)`
206+ float_from_components (
207+ :: Type{F} ,
208+ sign:: Real , exp:: Integer , mantissa:: Integer ,
209+ ) where {F<: AbstractFloat } =
210+ ldexp (sign * F (mantissa), exp)
211+
151212# # conversions to floating-point ##
152213
153214# TODO : deprecate in 2.0
0 commit comments