apprécier c'est un ancien poste, mais aussi les éléments suivants peuvent être utiles pour ceux qui cherchent pour faire cela en T-SQL (que j'étais).
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
Confirmation
0,125 est 0x 0000 0000 007E (ou 0X 7E00 0000 0000 inversés)
select dbo.ifn_HexReal48ToFloat('00000000007E', 0)
select dbo.ifn_HexReal48ToFloat('7E0000000000', 1)
l'entrée est un char12 comme je l'ai eu pour extraire le fichier binaire à partir du milieu de 2 d'autres plus grands champs binaires et les shunt ensemble ainsi l'avait déjà comme char12. Assez facile à changer pour être binaire (6) d'entrée si vous n'avez pas besoin de faire une manipulation à l'avance. En outre, dans le scénario que j'implémente, la variante T-SQL est surclassée par le code C# CLR, donc le code C# ci-dessus peut être meilleur. Bien que pas partout permet le code CLR dans SQL Server si vous pouvez alors peut-être vous devriez. Pour plus d'informations, un article au http://www.simple-talk.com/sql/t-sql-programming/clr-performance-testing/ fait une mesure en profondeur qui montre certaines différences dramatiques entre T-SQL et CLR.
Les gens utilisent toujours Real48? POURQUOI?! –
Où avez-vous besoin de les convertir? Dans un programme Delphi? –
@Ignacio: La rétrocompatibilité vient à l'esprit. –