我在 SQL Server 中有以字串格式存盤的數字
這些值僅在 0 和 1 中
declare @a varchar(max) = '100101001010100111010001010101011101010110100001010010111001'
declare @b varchar(max) = '010101100101010010101101001010100010100011010000101000100010'
a和b長度可達100,000位
我想將這兩個變數添加為數字
就像是
@a @b
結果應該是
110202101111110121111102011111111111110121110001111010211011
您可以看到這不是二進制添加...有2s
如何在 SQL Server 中執行此操作?
我試過這個
declare @a varchar(max) = '100101001010100111010001010101011101010110100001010010111001'
declare @b varchar(max) = '010101100101010010101101001010100010100011010000101000100010'
declare @ai bigint = cast(@a as bigint)
declare @bi bigint = cast(@b as bigint)
SELECT @ai @bi
但我收到了這個錯誤
訊息 8115,級別 16,狀態 2,第 4
行將運算式轉換為資料型別 bigint 的算術溢位錯誤。
訊息 8115,級別 16,狀態 2,第 5
行將運算式轉換為資料型別 bigint 的算術溢位錯誤。
我怎樣才能做到這一點?
uj5u.com熱心網友回復:
您可以使用 FLOAT(53):
declare @a varchar(max) = '100101001010100111010001010101011101010110100001010010111001'
declare @b varchar(max) = '010101100101010010101101001010100010100011010000101000100010'
declare @ai FLOAT(53) = cast(@a as FLOAT(53))
declare @bi FLOAT(53) = cast(@b as FLOAT(53))
結果SELECT @ai @b將為 1.1020210111111E 59 這將適用于您的示例輸入。但是 100.000 位作為數字資料型別是不可能的。
db<>小提琴
uj5u.com熱心網友回復:
您必須創建自己的計算器。
下面的代碼考慮了一些復雜的因素:
- 將數字轉換為字串時丟失前導零
- 在溢位的情況下將最重要的數字從一個批次轉移到下一個批次
例如:
declare @a varchar(max) = '100101001010100111010001010101011101010110100001010010311001'
declare @b varchar(max) = '010101100101010010101101001010100010100011010000101000900010'
declare @e varchar(max) = '110202101111110121111102011111111111110121110001111011211011' -- expected
declare @r varchar(max) = '' -- result
declare @batch_size int -- amount of digits to process at once
set @batch_size=18
declare @sum varchar(19) -- must be bigger than @batch_size
declare @carry bigint
set @carry = 0
declare @length int
set @length = LEN(@a) -- assumes LEN(@a) = LEN(@b)
declare @i int
set @i = @length / @batch_size
if @length % @batch_size = 0
set @i = @i - 1
while @i >= 0 begin
if @i * @batch_size @batch_size > @length begin
set @a = @a REPLICATE('0', @batch_size - @length % @batch_size)
set @b = @b REPLICATE('0', @batch_size - @length % @batch_size)
end
set @sum = CAST(SUBSTRING(@a, @i * @batch_size 1, @batch_size) AS bigint)
CAST(SUBSTRING(@b, @i * @batch_size 1, @batch_size) AS bigint)
@carry
set @carry = 0
if LEN(@sum) > @batch_size begin
set @carry = SUBSTRING(@sum, 1, 1)
set @sum = SUBSTRING(@sum, 2, @batch_size)
end
if LEN(@sum) < @batch_size
set @sum = REPLICATE('0', @batch_size - LEN(@sum)) @sum
if @i * @batch_size @batch_size > @length
set @sum = SUBSTRING(@sum, 1, @length - @i * @batch_size)
set @r = @sum @r
set @i = @i - 1
end
if @carry > 0
print 'overflow error'
if @r <> @e
print 'not the correct result'
select substring(@r,1,@length) as sum_of_a_and_b
uj5u.com熱心網友回復:
由于您的輸入數字受到限制1,0您可以執行以下操作。
首先創建一個數字表,其中的行數至少與最長的字串一樣多。
CREATE TABLE dbo.Numbers(Number INT PRIMARY KEY WITH (DATA_COMPRESSION = ROW));
INSERT dbo.Numbers
SELECT TOP 100000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM sys.all_columns c1, sys.all_columns c2
然后你可以做
declare @a varchar(max) = '100101001010100111010001010101011101010110100001010010111001'
declare @b varchar(max) = '10101100101010010101101001010100010100011010000101000100010'
declare @c varchar(max)
SELECT @c = STRING_AGG(0 SUBSTRING(normalised.a, Number, 1) SUBSTRING(normalised.B, Number, 1), '') WITHIN GROUP (ORDER BY Number)
FROM dbo.Numbers
CROSS APPLY(SELECT LEN(@a), LEN(@b)) lengths(len_a, len_b)
/*If @a and @b are not equal length add zeroes to left pad out the shorter one*/
CROSS APPLY (SELECT CONCAT(REPLICATE('0', len_b-len_a),@a), CONCAT(REPLICATE('0', len_a-len_b),@b)) normalised(a,b)
WHERE Number <= LEN(normalised.a)
PRINT @c
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/479627.html
下一篇:有沒有辦法自動遞增計數?
