在SQL Server中将基数10转换为基数2以获得非常大的数字
在SQL Server 2017上,我有一个以10为基数的数字类型在SQL Server中将基数10转换为基数2以获得非常大的数字,sql,sql-server,binary,decimal,Sql,Sql Server,Binary,Decimal,在SQL Server 2017上,我有一个以10为基数的数字类型DECIMAL(38,0),我需要将其转换为以2为基数的表示形式 这适用于较小的数字,但不适用于目标数量级: DECLARE @var1 DECIMAL(38, 0) = 2679226456636072036565806253187530752; WITH A AS (SELECT @var1 AS NUMBER, CAST('' AS VARCHAR(125)) AS BITS
DECIMAL(38,0)
,我需要将其转换为以2为基数的表示形式
这适用于较小的数字,但不适用于目标数量级:
DECLARE @var1 DECIMAL(38, 0) = 2679226456636072036565806253187530752;
WITH A
AS (SELECT @var1 AS NUMBER,
CAST('' AS VARCHAR(125)) AS BITS
UNION ALL
SELECT CAST(ROUND(NUMBER / 2, 0, 1) AS DECIMAL(38, 0)),
CAST(BITS + CAST(NUMBER % 2 AS VARCHAR(125)) AS VARCHAR(125))
FROM A
WHERE NUMBER > 0)
SELECT NUMBER,
RIGHT(REPLICATE('0', 125) + CASE
WHEN BITS = ''
THEN '0'
ELSE REVERSE(BITS)
END, 125) AS BIN_VALUE
FROM A
WHERE NUMBER = 0;
错误消息显示Msg 8115,级别16,状态2,第2行算术溢出错误将表达式转换为数据类型numeric。
我也尝试过其他方法,但由于原始值的大小,每种方法都失败了。非常感谢您在执行此转换过程中提供的任何帮助。如果您添加有关更改内容和原因的解释,将有助于您的回答。我不得不使用一个diff工具来查看您已将
NUMBER/2
更改为NUMBER*0.5
,并添加了选项(maxrecursion 0)
我接受了您的答案,因为它与我提供的示例一起工作,但现在我意识到,由于算术溢出返回,它在各种较大的值下都会失败。似乎我遇到了这个问题:我还没有找到解决办法。你可以在乘以0.1后,将数字分成两部分,得到由于乘法*0.5而产生的十进制数。高部分包含37位数字,而低部分添加在round()之后。您需要调整字符部分的长度,因为999..99(9x38倍)的二进制文件不适合125个字符…非常感谢@lptr!如果我能第二次投票支持你的答案,我会:)如果你能解释一下你改变了什么,为什么改变,这将有助于你的答案。我不得不使用一个diff工具来查看您已将NUMBER/2
更改为NUMBER*0.5
,并添加了选项(maxrecursion 0)
我接受了您的答案,因为它与我提供的示例一起工作,但现在我意识到,由于算术溢出返回,它在各种较大的值下都会失败。似乎我遇到了这个问题:我还没有找到解决办法。你可以在乘以0.1后,将数字分成两部分,得到由于乘法*0.5而产生的十进制数。高部分包含37位数字,而低部分添加在round()之后。您需要调整字符部分的长度,因为999..99(9x38倍)的二进制文件不适合125个字符…非常感谢@lptr!如果我能再次投票支持你的答案,我会:)因为我仍然遇到较大数字的溢出错误,我发布了一个后续问题:因为我仍然遇到较大数字的溢出错误,我发布了一个后续问题:
--DECLARE @var1 DECIMAL(38, 0) = 2679226456636072036565806253187530752;
DECLARE @var1 DECIMAL(38, 0) = 99999567999999999999999999999999999999;
WITH A
AS
(
SELECT @var1 AS NUMBER,
CAST('' AS VARCHAR(130)) AS BITS
UNION ALL
SELECT CAST(
cast(round(NUMBER*0.1, 0, 1) as decimal(38,0))*5 --high part
+
round(cast('0.'+right(NUMBER, 1) as decimal(10,2))* 5, 0, 1) --low part
--ROUND(NUMBER * 0.5, 0, 1)
AS DECIMAL(38, 0)),
CAST(BITS + CAST(NUMBER % 2 AS VARCHAR(125)) AS VARCHAR(130))
FROM A
WHERE NUMBER > 0
)
SELECT NUMBER,
RIGHT(REPLICATE('0', 130) + CASE
WHEN BITS = ''
THEN '0'
ELSE REVERSE(BITS)
END, 130) AS BIN_VALUE
FROM A
WHERE NUMBER = 0
option (maxrecursion 0);