I can't take full credit for this. I want to share this with Jeff Moden who did the important research for this calculation here.All I did was just adapting some old code according to the mantissa finding Jeff made and optimized it a little Some test codeDECLARE @SomeNumber FLOAT, @BinFloat BINARY(8)SELECT @SomeNumber = -185.6125, @BinFloat = CAST(@SomeNumber AS BINARY(8))SELECT @SomeNumber AS [Original], CAST(@SomeNumber AS BINARY(8)) AS [Binary], dbo.fnBinaryFloat2Float(CAST(@SomeNumber AS BINARY(8))) AS [Converted], @SomeNumber - dbo.fnBinaryFloat2Float(CAST(@SomeNumber AS BINARY(8))) AS [Error]
And here is the code for the function.CREATE FUNCTION dbo.fnBinaryFloat2Float( @BinaryFloat BINARY(8))RETURNS FLOATASBEGIN DECLARE @Part TINYINT, @PartValue TINYINT, @Mask TINYINT, @Mantissa FLOAT, @Exponent SMALLINT, @Bit TINYINT, @Ln2 FLOAT, @BigValue BIGINT SELECT @Part = 1, @Mantissa = 1, @Bit = 1, @Ln2 = LOG(2), @BigValue = CAST(@BinaryFloat AS BIGINT), @Exponent = (@BigValue & 0x7ff0000000000000) / EXP(52 * @Ln2) WHILE @Part <= 8 BEGIN SELECT @Part = @Part + 1, @PartValue = CAST(SUBSTRING(@BinaryFloat, @Part, 1) AS TINYINT), @Mask = CASE WHEN @Part = 2 THEN 8 ELSE 128 END WHILE @Mask > 0 BEGIN IF @PartValue & @Mask > 0 SET @Mantissa = @Mantissa + EXP(-@Bit * @Ln2) SELECT @Bit = @Bit + 1, @Mask = @Mask / 2 END END RETURN SIGN(@BigValue) * @Mantissa * POWER(CAST(2 AS FLOAT), @Exponent - 1023)END
Thanks again Jeff! Peter LarssonHelsingborg, Sweden