Appreciate that this is an old post, but the following may also be useful for those who want to do this in T-SQL (as I was).
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ifn_HexReal48ToFloat]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT')) drop function [dbo].[ifn_HexReal48ToFloat] go SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO create function [dbo].[ifn_HexReal48ToFloat] ( @strRawHexBinary char(12), -- NOTE. Do not include the leading 0x @bitReverseBytes bit ) RETURNS FLOAT AS BEGIN -- Reverse bytes if required -- eg 3FF4 0000 0000 is stored as -- 0000 0000 F43F declare @strNewValue varchar(12) if @bitReverseBytes = 1 begin set @strNewValue='' declare @intCounter int set @intCounter = 6 while @intCounter>=0 begin set @strNewValue = @strNewValue + substring(@strRawHexBinary, (@intCounter * 2) + 1,2) set @intCounter = @intCounter - 1 end end -- Convert the raw string into a binary declare @binBinaryFloat binary(6) set @binBinaryFloat = convert(binary(6),'0x' + isnull(@strNewValue, @strRawHexBinary),1) -- Based on original hex to float conversion at http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=81849 -- and storage format documented at -- http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/internaldataformats_xml.html -- Where, counting from the left -- Sign = bit 1 -- Exponent = bits 41 - 48 with a bias of 129 -- Fraction = bits 2 - 40 return SIGN ( CAST(@binBinaryFloat AS BIGINT) ) * -- Fraction part. 39 bits. From left 2 - 40. ( 1.0 + (CAST(@binBinaryFloat AS BIGINT) & 0x7FFFFFFFFF00) * POWER(CAST(2 AS FLOAT), -47) ) * -- Exponent part. 8 bits. From left bits 41 -48 POWER ( CAST(2 AS FLOAT), ( CAST(@binBinaryFloat AS BIGINT) & 0xff - 129 ) ) end
the confirmation
0.125 is 0x0000 0000 007E (or 0x 7E00 0000 0000 in reverse order)
select dbo.ifn_HexReal48ToFloat('00000000007E', 0) select dbo.ifn_HexReal48ToFloat('7E0000000000', 1)
The input is char12 because I had to extract the binary from the middle of two other larger binary fields and shunt them together if it was already char12. It is easy enough to switch to binary (6) input if you do not need to do any manipulations in advance.
As an aside, in the script that I am implementing, the T-SQL variant exceeded the C # CLR code, so the C # code above might be better. Although itβs not always possible to use the CLR code in SQL Server, if you then may need to. For more information, the article http://www.simple-talk.com/sql/t-sql-programming/clr-performance-testing/ makes some depth measurements that show some significant differences between T-SQL and CLR.
Simon molloy
source share