Coi trọng này là một bài cũ, nhưng cũng sau đây có thể hữu ích cho những người tìm kiếm để làm điều này trong T-SQL (mà tôi đã).
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
Chứng nhận
0,125 là 0x 0000 0000 007E (hoặc 0x 7E00 0000 0000 đảo ngược)
select dbo.ifn_HexReal48ToFloat('00000000007E', 0)
select dbo.ifn_HexReal48ToFloat('7E0000000000', 1)
Đầu vào là một char12 như tôi đã phải trích xuất các nhị phân từ giữa 2 các trường nhị phân lớn hơn và shunt chúng lại với nhau vì vậy đã có nó như là char12. Dễ dàng đủ để thay đổi thành đầu vào nhị phân (6) nếu không cần thực hiện bất kỳ thao tác nào trước đó.
Là một sang một bên, trong kịch bản mà tôi đang triển khai, biến thể T-SQL được cải thiện tốt hơn mã C# CLR để mã C# ở trên có thể tốt hơn. Trong khi không phải ở khắp mọi nơi cho phép mã CLR vào SQL Server nếu bạn có thể thì có lẽ bạn nên. Để biết thêm chi tiết, một bài báo ở số http://www.simple-talk.com/sql/t-sql-programming/clr-performance-testing/ thực hiện một số phép đo chiều sâu cho thấy một số khác biệt đáng kể giữa T-SQL và CLR.
Nguồn
2011-11-11 09:50:37
Mọi người vẫn đang sử dụng Real48? TẠI SAO?! –
Bạn cần chuyển đổi chúng ở đâu? Trong một chương trình Delphi? –
@Ignacio: Khả năng tương thích ngược sẽ xuất hiện trong đầu bạn. –