собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?
Здравствуйте, Zip, Вы писали:
Zip>собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?
См. classes.pas, класс TBits. У него, правда, поле FBits объявлено как private, поэтому записать его в файл просто так не получится. Но изобразить на его основе свой класс с нужной функциональностью несложно.
Здравствуйте, Softwarer, Вы писали:
S>Здравствуйте, Zip, Вы писали:
Zip>>Но ведь это же глупо. Веть нужем всего одит бит.
S>На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта.
Ну так то файл, а то память
S>Если по-прежнему стремишься к эффективности — прочитай про множества. Это не единственный, но самый простой способ.
Сначала надо читать про битовые операции, а потом уже изучать фичи языка/компилятора.
Здравствуйте, Zip, Вы писали:
Zip>собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?
Держи, писать 5 минут. Посмотри хоть как делается
type
TBoolArray = array of Boolean;
procedure ArrayToBit (BoolArray : TBoolArray; out Ptr : Pointer; out Size : Integer {in bytes});
var
K: Integer;
aCurrentByte : PChar;
begin
Size := Length (BoolArray) div 8 + 1;
GetMem (Ptr, Size);
try
FillChar (Ptr^, Size, 0);
for K := 0 to Length (BoolArray) - 1 do begin
if BoolArray [K] then begin
aCurrentByte := PChar (Ptr) + K div 8;
Byte ((aCurrentByte)^) := Byte ((aCurrentByte)^) or (1 shl (K mod 8));
end;
end;
except
FreeMem (Ptr);
raise;
end;
end;
function IsBitSet (Ptr : Pointer; Size : Integer; Index : Integer) : Boolean;
var
aByteIndex : Integer;
aCurrentByte : PChar;
begin
aByteIndex := Index div 8;
if aByteIndex >= Size then
raise Exception.Create ('Index is out of Range');
aCurrentByte := PChar (Ptr) + aByteIndex;
Result := Byte (aCurrentByte^) and (1 shl (Index mod 8)) <> 0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
K: Integer;
aBoolArray : TBoolArray;
aPtr : Pointer;
aSize : Integer;
begin{ Test proc }
SetLength (aBoolArray, 10);
for K := 0 to Length (aBoolArray) - 1 do
aBoolArray [K] := False;
aBoolArray [0] := True;
aBoolArray [9] := True;
ArrayToBit (aBoolArray, aPtr, aSize);
try
for K := 1 to 8 do begin
if IsBitSet (aPtr, aSize, K) then
raise Exception.Create ('Test failed');
end;
if not IsBitSet (aPtr, aSize, 0) then
raise Exception.Create ('Test failed');
if not IsBitSet (aPtr, aSize, 9) then
raise Exception.Create ('Test failed');
finally
FreeMem (aPtr);
end;
end;
Здравствуйте, Softwarer, Вы писали:
S>На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта.
Почему И где — во внешней памяти или оперативной? Кеши трех уровней считать, пожалуй, не будем Для начала, неясно, что такое "занимает". Тогда уж правильнее говорить об "отнимает" (полезного объема памяти). Но если во внешней памяти — почему именно 542?
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Здравствуйте, Slicer [Mirkwood], Вы писали:
S>>На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта. SM>Почему И где — во внешней памяти или оперативной? Кеши трех уровней считать, пожалуй, не будем
Для файла оперативка — такой же кэш. Считать кэши не стоит, поскольку они не "занимаются", а "используются" — хотя это тоже имеет значение
SM>Для начала, неясно, что такое "занимает". Тогда уж правильнее говорить об "отнимает" (полезного объема памяти). Но если во внешней памяти — почему именно 542?
Хм. Хороший вопрос. Видимо, в столь ранний час я был совершенно уверен, что сумма одного блока и одной записи в каталоге составит именно это число (байты ECC не считаем )
P.S. Видимо, пора брать мораторий на вентиляцию мозгов.
Hello Zip, you wrote:
> собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?
Если хочется написать самому, то смотри в сторону ассемблерных функций bt, bts, btr.
Хотя можно обойтись и при помощи and, or, shl.