Примите во внимание, что это старый пост, но также может быть полезно следующее для тех, кто хочет сделать это в T-SQL (которым я был).
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
-- e.g. 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
Подтверждение
0,125 - это 0x 0000 0000 007E (или 0x 7E00 0000 0000 в обратном порядке)
select dbo.ifn_HexReal48ToFloat('00000000007E', 0)
select dbo.ifn_HexReal48ToFloat('7E0000000000', 1)
Вводом является char12, так как мне пришлось извлечь двоичный файл из середины двух других больших двоичных полей и смешать их вместе, так что он уже был как char12. Достаточно легко изменить на двоичный (6) ввод, если не нужно предварительно выполнять какие-либо манипуляции.
Кроме того, в сценарии, который я реализую, вариант T-SQL превосходит код C # CLR, поэтому приведенный выше код C # может быть лучше. Хотя не везде позволяет CLR-код в SQL Server, если вы можете, возможно, вам следует. Для получения дополнительной информации в статье http://www.simple -talk.com / sql / t-sql-программирование / clr-performance-Testing / проведено некоторое углубленное измерение, которое показывает некоторые существенные различия между T-SQL и CLR .