Значение
A BigInt
может содержать 64 бита.Используя целочисленное деление и побитовые операторы, вы можете возиться с битами.Следующий код демонстрирует выбор младшего значащего бита из значения, сдвиг вправо и повторение.Добавление where LSB = 1
к окончательному select
отфильтрует четные значения.
declare @Foo as BigInt = 0x0F00700FF0F0; -- '0000 1111 0000 0000 0111 0000 0000 1111 1111 0000 1111 0000'
select @Foo as Foo, Cast( @Foo as VarBinary(6) ) as FooHex;
with ShiftedBits as (
-- Start with the original value and pick off the least-significant-bit.
select @Foo as Foo, 0 as Position, @Foo & 1 as LSB
union all
-- Right shift the value and repeat.
select Foo / 2, Position + 1, Foo / 2 & 1
from ShiftedBits
where Position < 47 )
-- Display the value, position and bit.
select Foo, Cast( Foo as VarBinary(6) ) as FooHex, Position, LSB
from ShiftedBits
order by Position;
В качестве альтернативы, если у вас есть таблица чисел со степенями двух, вы можете просто маскировать биты без рекурсии:
declare @Foo as BigInt = 0x0F00700FF0F0; -- '0000 1111 0000 0000 0111 0000 0000 1111 1111 0000 1111 0000'
select @Foo as Foo, Cast( @Foo as VarBinary(6) ) as FooHex;
-- Create a powers-of-two table.
declare @PowersOfTwo as Table ( P Int, P2 BigInt );
with PowersOfTwo as (
select 0 as P, Cast( 1 as BigInt ) as P2
union all
select P + 1, P2 * 2
from PowersOfTwo
where P < 47 )
insert into @PowersOfTwo
select P, P2
from PowersOfTwo;
select *, Cast( P2 as VarBinary(6) ) as P2Hex from @PowersOfTwo order by P;
-- Pick the bits.
select P, P2, Cast( P2 as VarBinary(6) ) as P2Hex,
Cast( @Foo & P2 as VarBinary(6) ) as MaskedBit,
Cast( @Foo / P2 as VarBinary(6) ) as ShiftedValue,
case when @Foo & P2 = 0 then 'bad' else 'good' end as Keeper
from @PowersOfTwo;