8 булевых переменных в одном байте.
От: Zip Россия none
Дата: 04.04.05 23:25
Оценка:
собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?
Re: 8 булевых переменных в одном байте.
От: Softwarer http://softwarer.ru
Дата: 05.04.05 04:57
Оценка:
Здравствуйте, Zip, Вы писали:

Zip>Но ведь это же глупо. Веть нужем всего одит бит.


На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта.

Если по-прежнему стремишься к эффективности — прочитай про множества. Это не единственный, но самый простой способ.
Re: 8 булевых переменных в одном байте.
От: Sergei I. Gorelkin Россия  
Дата: 05.04.05 05:41
Оценка:
Здравствуйте, Zip, Вы писали:

Zip>собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?


См. classes.pas, класс TBits. У него, правда, поле FBits объявлено как private, поэтому записать его в файл просто так не получится. Но изобразить на его основе свой класс с нужной функциональностью несложно.
Re[2]: 8 булевых переменных в одном байте.
От: Jack128  
Дата: 05.04.05 06:00
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, Zip, Вы писали:


Zip>>Но ведь это же глупо. Веть нужем всего одит бит.


S>На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта.


Ну так то файл, а то память

S>Если по-прежнему стремишься к эффективности — прочитай про множества. Это не единственный, но самый простой способ.


Сначала надо читать про битовые операции, а потом уже изучать фичи языка/компилятора.
Re[3]: 8 булевых переменных в одном байте.
От: Softwarer http://softwarer.ru
Дата: 05.04.05 06:22
Оценка:
Здравствуйте, Jack128, Вы писали:

J>Сначала надо читать про битовые операции, а потом уже изучать фичи языка/компилятора.


В целом — полностью согласен. Но я сейчас не чувствую в себе сил читать лекцию по битовым операциям, поэтому подчеркнул максимально простое решение.
Re: 8 булевых переменных в одном байте.
От: Danchik Украина  
Дата: 05.04.05 07:44
Оценка:
Здравствуйте, 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;
Re[2]: 8 булевых переменных в одном байте.
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 06.04.05 16:11
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта.

Почему И где — во внешней памяти или оперативной? Кеши трех уровней считать, пожалуй, не будем Для начала, неясно, что такое "занимает". Тогда уж правильнее говорить об "отнимает" (полезного объема памяти). Но если во внешней памяти — почему именно 542?

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[3]: 8 булевых переменных в одном байте.
От: Softwarer http://softwarer.ru
Дата: 06.04.05 17:45
Оценка:
Здравствуйте, Slicer [Mirkwood], Вы писали:

S>>На самом деле все гораздо глупее. Когда ты создаешь файл с восемью булевыми переменными, он занимает минимум пятьсот сорок два байта.

SM>Почему И где — во внешней памяти или оперативной? Кеши трех уровней считать, пожалуй, не будем

Для файла оперативка — такой же кэш. Считать кэши не стоит, поскольку они не "занимаются", а "используются" — хотя это тоже имеет значение

SM>Для начала, неясно, что такое "занимает". Тогда уж правильнее говорить об "отнимает" (полезного объема памяти). Но если во внешней памяти — почему именно 542?


Хм. Хороший вопрос. Видимо, в столь ранний час я был совершенно уверен, что сумма одного блока и одной записи в каталоге составит именно это число (байты ECC не считаем )

P.S. Видимо, пора брать мораторий на вентиляцию мозгов.
Re: 8 булевых переменных в одном байте.
От: Slava Antonov Россия http://deadbeef.narod.ru
Дата: 16.04.05 00:50
Оценка:
Hello Zip, you wrote:

> собственно сабж. Есть массив записей, в нем много булевых переменных. Когда я создаю типизированный файл этих записей каждая булевая переменная получает один байт на хранение. Но ведь это же глупо. Веть нужем всего одит бит. Как я могу имея к примеру переменную BollArray:byte, упаковать в неё булевые переменные. И как потом получить к ним доступ?


Если хочется написать самому, то смотри в сторону ассемблерных функций bt, bts, btr.
Хотя можно обойтись и при помощи and, or, shl.

Либо смотри уже готовое решение — TBits.

--
Всего хорошего, Слава
Posted via RSDN NNTP Server 1.9
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.