Недавно на лекции услышал впервые этот термин.И кое-что я не могу понять.
Я знаю,что в Delphi нет такой готовой стркутры данных,максимум есть array of byte.И у меня вопрос а как его тогда создать?
Например:есть array [1..3] of byte .Как мне из него сделать битовый массив из 24 элементов и к примеру занести единицы в 3-ий и 17-ий бит?
Заранее спасибо.В интернете искал,но ничего похожего не нашёл.
Я знаю,что в Delphi нет такой готовой стркутры данных,максимум есть array of byte.И у меня вопрос а как его тогда создать?
Например:есть array [1..3] of byte .Как мне из него сделать битовый массив из 24 элементов и к примеру занести единицы в 3-ий и 17-ий бит?
Заранее спасибо.В интернете искал,но ничего похожего не нашёл.
byteIdx:=i shr 3; //получаем индекс байта в массиве
bitIdx:=i and 7; // получаем индекс бита в этом байте
mask:=1 shl bitIdx; // получаем маску
b:=bArr[byteIdx]; //получаем интересующий нас байт
b:= b or mask; //устанавливаем нужный бит
bArr[byteIdx]:=b; //загоняем модифицированный байт обратно в массив
Здесь я считаю, что bArr индексируется с нуля (привык я так), если это не так, надо просто к byteIdx прибавить номер первого элемента. Т.е. для array [1..3] of byte это будет byteIdx:=(i shr 3) +1;
Для того, чтобы получить значение i'го бита, делаем так:
byteIdx:=i shr 3; //получаем индекс байта в массиве
bitIdx:=i and 7; // получаем индекс бита в этом байте
b:=bArr[byteIdx]; //получаем интересующий нас байт
b:= b shr bitIdx; //сдвигаем побитово значение b так, чтобы интересующий нас бит был первым
bitVal:=b and 1; // очищаем все неинтересные нам биты
A:array[0..1] of byte .Для начала там будет два нуля.Или {0000 0000;0000 0000}.Мне нужно сделать {0000 0000;0000 1000} и потом считать номер где находится эта единица.
Тогда byteIdx:=13 shr 3 = 1101 shr 3 = 0001 = 1 .BitIdx:=1101 and 0111 = 0101 = 5.Вроде пока всё верно.Но вот дальше возникают проблемы.mask := 1 shl 5 =
0001 shl 5 = 0000 ? или 00001 shl 5 = 10000 ? Интуиция всё таки подсказывает,что mask = 1000 .Дальше b:= Arr[1]= 0. b:= 0000 or 1000 = 1000(0000 1000).Тогда
Arr[1]:={0000 1000}.То есть п.1 вроде бы ясно,но остался вопрос насчёт маски,которую я не могу понять и для чего она вообще нужна.
Теперь нужно считать номер этой единицы.byteIdx:=1 ; bitIdx:=5 .b:=Arr[1]=8 .b:= 1000 0000(бит стал первым) .bitval:=1000 0000 and 0000 0001 = 0.
Ещё один вопрос:а зачем нам сдвигать число,чтобы бит становился первым?Что это даёт?И как можно получить из этого всего искомое число 13?И мне к сожалению не понятно
какая переменная содержит значение i-го бита
-- это 4 бит, а не 13.
> И как можно получить из этого всего искомое число 13?
Никак, ты же записываешь "1" или "0", только тру или фолс, для записи чисел надо использовать обычный массив чисел
Далее. В данном примере в массиве получаются установленными биты 0,1,5,6,9,15 и 13 (который мы только что установили). Просто число 13, равно как и числа 0,1,5,6,9,15 просто так получить не выйдет. Однако, можно проверить, установлен ли какой-то конкретный бит - что в общем-то и требуется при практическом применении битовых массивов.
Проверим, установлен ли бит, скажем, 15 в массиве A.
Получили 1 - т.е. значение 15'го бита. Хотя в принципе, ты прав, это не обязательно. Сравнение с нулём значения A[byteIdx ] and mask тоже может сказать, установлен интересующий нас бит или нет.
Да, должен покаяться, с дельфями я уже лет шесть дела не имел и расписал подход, который больше в ходу в среде программистов на си-подобных языках. Как верно было подмечено A r i s e n, есть такой тип в дельфях - Set. Это по сути - битовый массив в 32 байта (т.е. 256 бит) максимум, все битовые операции с которым компилятор делфи прописывает за программиста. Для большинства практических задач этого должно хватать с лихвой. Мною же озвученный подход необходим, если приходится оперировать большими, нежели 256 бит, массивами (с учётом ограничений делфи на длину массива - до полугигабита). Ну, или если хочется "чувствовать память" =)
Там ведь A[1] or mask .А так всё понятно.Про set: я бы рад,но мне в задаче нужно создать битовый массив из 7*10^7 чисел)Ещё раз спасибо
Да, естественно, описался, спасибо, что подметили. И что забавно - я ведь когда писал, заметил эту описку, и даже вроде бы исправил... =)