在 SQL Server 中将 1 和 0 的 32 位二进制字符串转换为有符号十进制数



我正在使用SQL Server 2012 Express。我有一个长度为32位的1和0的字符串

01010010000100010111001101110011

如何在SQL脚本中将其转换为有符号十进制数?

目前我使用一个网络工具在线为我的答案,我目前的搜索并没有引导我到我需要的答案。

如果使用一个统计表,则可以使用单个T-SQL语句执行转换:

;WITH Tally(i) AS (
   SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS i
   FROM (VALUES (0), (0), (0), (0), (0), (0), (0), (0)) a(n)
   CROSS JOIN (VALUES (0), (0), (0), (0)) b(n)
)  
SELECT SUM(t.v) AS DecimalNumber 
FROM (
   SELECT POWER(CAST(SUBSTRING(x.d, i, 1) AS DECIMAL(10,0)) * 2, 32 - i)
   FROM (VALUES ('01010010000100010111001101110011')) x(d)
   CROSS JOIN Tally) AS t(v)

解释:

  • Tally是一个表表达式,返回1-32之间的所有值。
  • 使用这些值,我们可以使用SUBSTRING提取二进制字符串中的每一个数字。
  • 使用POWER数学函数可以将每个单独的二进制数转换为十进制数。
  • 使用SUM,我们可以将所有单独的十进制数字相加以得到预期的结果。

演示

你可以尝试如下-

DECLARE @Binary VARCHAR(100) = '01010010000100010111001101110011';
DECLARE @characters CHAR(36),  
        @result BIGINT,  
        @index SMALLINT,  
        @base BIGINT;
SELECT @characters = '0123456789abcdefghijklmnopqrstuvwxyz',  
       @result = 0,  
       @index = 0,
       @base = 2;    
WHILE @index < LEN(@Binary)
BEGIN 
     SELECT @result = @result + POWER(@base, @index) * (CHARINDEX(SUBSTRING(@Binary, LEN(@Binary) - @index, 1), @characters) - 1);
     SET @index = @index + 1;  
END
SELECT @result;

这将帮助您从任何基数(我使用@base as 2二进制)转换为基数10。从最右边开始,移到最左边,直到没有数字了。转换为(base ^ index) *数字

除了Giorgos Betsos的回复见以下ITVF功能:

CREATE FUNCTION [dbo].[udf_BinaryToDecimal]
(
 @Binary VARCHAR(31)
)
  RETURNS TABLE AS RETURN
  WITH Tally (n) AS
 (
 --32 Rows
    SELECT TOP (LEN (@Binary)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1
    FROM (VALUES (0),(0),(0),(0)) a(n)
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
 )
 SELECT 
 SUM(SUBSTRING(REVERSE(@Binary),n+1,1)  *  POWER(2,n)) TenBase
 FROM Tally 
 /*How to Use*/
 SELECT TenBase 
 FROM udf_BinaryToDecimal ('01010010000100010111')
 /*Result -> 336151*/

我必须将这段代码添加到Abhishek的代码示例的末尾,以获得我需要的有符号数字。

DECLARE @MyNewExValue INT
IF @result > 2147483647
     BEGIN
         SET @result = @result - (2147483648 * 2)
     END
SET @MyNewExValue = @result
SELECT @MyNewExValue

此解决方案适用于任何(bigint)长度的二进制字符串:

DECLARE @input varchar(max) = 
  '01010010000100010111001101110011'
;WITH N(V) AS 
(
  SELECT
    ROW_NUMBER()over(ORDER BY (SELECT 1))
  FROM
    (VALUES(1),(1),(1),(1))M(a),
    (VALUES(1),(1),(1),(1))L(a),
    (VALUES(1),(1),(1),(1))K(a)
)
SELECT SUM(SUBSTRING(REVERSE(@input),V,1)*POWER(CAST(2 as BIGINT), V-1))
FROM   N
WHERE  V <= LEN(@input)

(源)

应该注意的是,上面最受欢迎的解决方案仅适用于长度为32位的二进制字符串,并且字符串'00000000000000000000000000000000'返回1

相关内容

  • 没有找到相关文章