Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 разложить на битовый массив  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
всезнающий алл, может кто-то сталкивался, подскажите, пожалуйста, как сделать такую задачку
имею таблицу со значениями в полях
a 776
b 264
c 296
d 64
необходимо вывести результат

a 512
a 256
a 8
b 256
b 8
c 256
c 32
c 8
d 64

вроде в институте что-то делал подобное. но не могу уже вспомнить как.
раскладывать нужно на фиксированные элементы массива 2 4 8 16 32 64 128 256 512 1024 2048 4096
только значения для раскладывания могут быть различными, но факт, что значения должны раскладываться без остатка
спасибо
24 окт 14, 00:23    [16751702]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
так,
Guest
Двоичник,

рекурсивное СТЕ поможет

берёшь в "якоре" какую-нибудь, заведомо большую макс числа степень 2-ки,
сравниваешь с числом, если меньше числа, то 2^n в "накопитель", остаток = разность тек.остатка с 2^n, степень уменьшаешь на единицу, и "уходишь" в рекурсию, пока остаток > 0
24 окт 14, 01:00    [16751796]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
aleks2
Guest
так,

рекурсивное СТЕ поможет

Что за бред?

declare @2n table ([2^n] int primary key clustered)

insert @2n
select 2 union all select 4 union all select 8 union all select 16 union all select 32 union all select 64

declare @t table(n int, ch char(1))

insert @t select 64, 'a' union all select 66, 'b'

select * from @t t inner join @2n n on n&[2^n] > 0 order by ch, [2^n]
24 окт 14, 06:14    [16751934]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
LexusR
Member

Откуда: Novosibirsk
Сообщений: 1873
declare @t table(n int, ch char(1))
insert @t select 64, 'a' union all select 66, 'b' union all select 23536490, 'c'

select t.*,POWER(2,n.Number) as [2^n] 
from @t t inner 
join master.dbo.spt_values n
on n.type ='P' and n.number<=30    
and POWER(2,n.Number)&t.n>0
24 окт 14, 07:38    [16751975]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
aleks2
Guest
LexusR
declare @t table(n int, ch char(1))
insert @t select 64, 'a' union all select 66, 'b' union all select 23536490, 'c'

select t.*,POWER(2,n.Number) as [2^n] 
from @t t inner 
join master.dbo.spt_values n
on n.type ='P' and n.number<=30    
and POWER(2,n.Number)&t.n>0


Если это "зачОт сдать", то на троечку сойдет.
Если реально использовать - это пример образцово-показательной неправильной реализации.
Ибо нафига грузить сервер ненужными вычислениями?
24 окт 14, 09:49    [16752302]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
vova ivanov
Member [заблокирован]

Откуда:
Сообщений: 1090
aleks2
так,
рекурсивное СТЕ поможет

Что за бред?

чойта ?
declare @t table (n int, ch char(1))

insert into @t (ch, n)
select 'a', 776 union all
select 'b', 264 union all
select 'c', 296 union all
select 'd', 64

-----------------------------------------------
-- я про такое писал 

;with cte as
(select ch, n, 30-1 as pwr, case when n>=power(2,30) then power(2,30) else 0 end as res, case when n>=power(2,30) then n-power(2,30) else n end as rem
from @t

union all

select ch, n, pwr-1, case when rem>=power(2,pwr) then power(2,pwr) else 0 end as res, case when rem>=power(2,pwr) then rem-power(2,pwr) else rem end as rem 
from cte
where pwr>0)

select ch, res from cte where res>0 order by 1

-----------------------------------------------
-- ну, а с битовым AND совсем просто

;with cte as
(select ch, n, 30-1 as pwr, n & power(2,30) as res
from @t

union all

select ch, n, pwr-1, n & power(2,pwr) as res
from cte
where pwr>0)

select ch, res from cte where res>0 order by 1

ch   res
---- -----------
a    512
a    256
a    8
b    256
b    8
c    256
c    32
c    8
d    64

(9 row(s) affected)
24 окт 14, 10:07    [16752374]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
Soldat
Member

Откуда: Москва
Сообщений: 854
Это что, курсовая?

Ну если не заниматся динамическим формированием степени двойки,
то можно простым соединением отсечь и размножить все варианты.
Хотя @mask можно и на лету построить.
declare @input table (name varchar(20), w bigint)
insert into @input (name, w) values ('a', 776), ('b', 264), ('c', 296), ('d', 64)

declare @mask table (w bigint, i tinyint)
insert into @mask (w, i) values (1, 0), (2,1), (4,2), (8,3), (16,4), (32,5), (64,6), (128,7), (256,8), (512,9), (1024,10)

select i.name, m.w, m.i
from @input i 
	inner join @mask m on m.w & i.w > 0
order by 1

name	w	i
--------------------
a	8	3
a	256	8
a	512	9
b	8	3
b	256	8
c	8	3
c	32	5
c	256	8
d	64	6
24 окт 14, 10:32    [16752502]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
Двоичник
Member

Откуда: Бобруйск
Сообщений: 292
спасибо Soldat
нет, это не курсовая.
это кто-то до меня программист, сделал такую таблицу, а как приджоинить справочник, ума не приложу. вроде что-то вот нативное, и вспомнить не могу.
руки бы оторвать за такие дикие методы.
хотя по примеру Soldat совсем не дикий.
24 окт 14, 11:31    [16752896]     Ответить | Цитировать Сообщить модератору
 Re: разложить на битовый массив  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Рассмотрите вариант о хранении битовых данных в битовых же полях.
24 окт 14, 11:36    [16752925]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить