apprezzare questo è un vecchio post, ma anche quanto segue può essere utile per coloro che cercano per farlo in T-SQL (che ero).
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
Conferma
0,125 0x 0000 0000 007E (o 0x 7E00 0000 0000 invertito)
select dbo.ifn_HexReal48ToFloat('00000000007E', 0)
select dbo.ifn_HexReal48ToFloat('7E0000000000', 1)
l'ingresso è un char12 come ho dovuto estrarre il binario da metà 2 altri campi binari più grandi e li shunt insieme così lo aveva già come char12. Abbastanza facile da cambiare per essere un input binario (6) se non è necessario eseguire alcuna manipolazione in anticipo.
Per inciso, nello scenario in cui sto implementando, la variante T-SQL è sovraperformata dal codice CLR C# in modo che il codice C# sopra possa essere migliore. Anche se non dappertutto consente il codice CLR in SQL Server se è quindi possibile che si dovrebbe. Per ulteriori informazioni, un articolo su http://www.simple-talk.com/sql/t-sql-programming/clr-performance-testing/ esegue una misurazione in profondità che mostra alcune differenze notevoli tra T-SQL e CLR.
fonte
2011-11-11 09:50:37
Le persone usano ancora Real48? PERCHÉ?! –
Dove hai bisogno di convertirli? In un programma Delphi? –
@Ignacio: mi viene in mente la compatibilità con le versioni precedenti. –