SQL_scripts
/
сложение в разных системах исчисления.sql
211 строк · 4.1 Кб
1--1 ВАРИАНТ числа в одной системе
2--указать два числа в одной системе и базу системы (от 2 до 36)
3
4declare
5@number1 varchar(100) = 'f1f'
6,@number2 varchar(100) = '1f1'
7,@base int = 16
8
9set nocount on
10
11declare
12@array varchar(100) = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z'
13,@separator varchar(1) = ','
14,@dec bigint
15,@out varchar(100)
16
17if len(@number2) > len(@number1)
18begin
19set @out = @number1
20set @number1 = @number2
21set @number2 = @out
22set @out = null
23end
24
25declare @digits table (num int primary key)
26
27;with ten as (
28select n
29from (values (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) as t(n)
30),cte as (
31select row_number() over(order by (select null)) as n
32from
33ten as t1
34cross join ten as t2
35cross join ten as t3
36)
37insert into @digits (num)
38select n from cte
39
40declare @dict table (
41ord int
42,val varchar(1) primary key
43)
44
45insert into @dict (ord, val)
46select top (@base)
47row_number() over(order by (select null)) - 1
48,cast(s.[value] as varchar(1))
49from string_split(@array, @separator) as s
50
51;with c1 as (
52select top (len(@number1))
53t.num
54,substring(@number1, row_number() over(order by t.num), 1) as symb
55from @digits as t
56order by t.num
57), c2 as (
58select top (len(@number2))
59t.num
60,substring(@number2, row_number() over(order by t.num), 1) as symb
61from @digits as t
62order by t.num
63), t1 as (
64select
65t.symb
66,row_number() over(order by t.num desc) as ord
67,d.ord as val
68from
69c1 as t
70inner join @dict as d
71on d.val = t.symb
72), t2 as (
73select
74t.symb
75,row_number() over(order by t.num desc) as ord
76,d.ord as val
77from
78c2 as t
79inner join @dict as d
80on d.val = t.symb
81
82), s as (
83select
84isnull(t1.val, 0) as val1
85,isnull(t2.val, 0) as val2
86,t1.ord
87from
88t1
89full join t2
90on t1.ord = t2.ord
91union all
92select
930
94,0
95,(select max(ord) + 1 from t1)
96), r as (
97select
98s.ord
99,s.val1
100,s.val2
101,(s.val1 + s.val2) / @base as Tnf
102,((s.val1 + s.val2) % @base) as newVal
103from s
104where s.ord = 1
105union all
106select
107s.ord
108,s.val1
109,s.val2
110,((s.val1 + s.val2 + r.Tnf) / @base) as Tnf
111,((s.val1 + s.val2 + r.Tnf) % @base) as newVal
112from
113s
114inner join r
115on r.ord + 1 = s.ord
116), w as (
117select
118r.ord
119,d.val
120from
121r
122inner join @dict as d
123on d.ord = r.newVal
124)
125select @out = string_agg(val, '') within group (order by ord desc)
126from w
127
128select @out
129
130go
131
132--2 ВАРИАНТ число в любой системе, а инкремент в десятичной
133
134declare
135@number varchar(100) = 'fff' --число в системе база которой указывается в @base
136,@base int = 16
137,@dec_inc int = 5 -- десятичный инкремент
138
139--
140set nocount on
141
142declare
143@array varchar(100) = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z'
144,@separator varchar(1) = ','
145,@dec bigint
146,@out varchar(100)
147
148declare @digits table (num int)
149
150;with ten as (
151select n
152from (values (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) as t(n)
153),cte as (
154select row_number() over(order by (select null)) as n
155from
156ten as t1
157cross join ten as t2
158cross join ten as t3
159)
160insert into @digits (num)
161select n from cte
162
163declare @dict table (
164ord int
165,val varchar(1)
166)
167
168insert into @dict (ord, val)
169select top (@base)
170row_number() over(order by (select null)) - 1
171,cast(s.[value] as varchar(1))
172from string_split(@array, @separator) as s
173
174;with t as (
175select top (len(@number))
176t.num
177,substring(@number, row_number() over(order by t.num), 1) as val
178from @digits as t
179order by t.num
180), s as (
181select d.ord * power(@base, row_number() over(order by t.num desc) - 1) as val
182from
183t
184inner join @dict as d
185on t.val = d.val
186)
187select @dec = sum(val)
188from s
189
190set @dec += @dec_inc
191
192;with rec as (
193select
194@dec / @base as [dec]
195,(select val from @dict where ord = @dec % @base) as val
196,0 as ord
197union all
198select
199r.[dec] / @base
200,d.val
201,r.ord + 1
202from
203rec as r
204inner join @dict as d
205on d.ord = r.[dec] % @base
206where not (r.[dec] / @base = 0 and r.[dec] % @base = 0)
207)
208select @out = string_agg(val, '') within group (order by ord desc)
209from rec
210
211select @out as result
212
213
214