Войти
ПрограммированиеФорумОбщее

Вопросы по Delphi (5 стр)

Страницы: 14 5 6 756 Следующая »
#60
14:45, 18 мая 2022

CD
это только для целых чисел или для всего?

#61
(Правка: 15:13) 15:09, 18 мая 2022

g-cont
Почти, это только для Ordinal Types (целые (кроме UInt64, он глючит), перечисления (куда входит Boolean), строковые символы)

const
  WA = WideChar('A');
  WZ = WideChar('Z');
  AA = AnsiChar('A');
  AZ = AnsiChar('Z');
type
  tx = (x0, x1, x2);
var
  x: x0..x1;
  y:  -1..1;
  z: false..false;
  a: WA..WZ; //2 байта
  b: AA..AZ; //1 байт
  с: '0'..'9'; //зависит от версии делфи
  gg: array[x0..x2] of Integer; //можно еще так применять
#62
(Правка: 10:27) 10:20, 22 мая 2022

  Тут такой вопрос(причем очень нужный) возник(касается LCL Лазаруса скорее). В каком модуле есть что-то наподобие IndexOfByte, но с проверкой не на первую попавшуюся ячейку памяти из определенного интервала с соотвествующим значением, а именно чтоб вместо равенства было наоборот отличие от заданного значения? Или может у кого есть ассемблерная функция? Уж больно шустрая данная функция(как минимум в 7 раз быстрее простого сдвига и проверки разыменованного указателя).

#63
11:04, 22 мая 2022

ArtProg
> простого сдвига и проверки
Умножай байт на $01010101 и проверяй сразу 4 байта, или если 64-битный код, то на $0101010101010101 и сразу 8 байт

#64
12:03, 22 мая 2022

  Интересная идея, надо будет проверить позже. Спасибо!

#65
(Правка: 6:27) 6:04, 23 мая 2022

  Увы, но не работает как надо. Точнее обнаруживается только первый, отличный од заданного значения байт(а надо произвольный) в цепочке из восьми байтов. Вот наглядные примеры:

var
  arr    : array of byte;
  arr_ptr: PByte;
  i      : integer;
begin
  SetLength(arr,8);
  arr_ptr:=@arr[0];
  arr[0]:=1;
  if (((arr_ptr+0)^ and $0101010101010101)<>0) then
    Writeln('arr[0] is not 0;')
  else
    Writeln('arr[0] is 0;');
  arr[0]:=0;
  arr[1]:=1;
  if (((arr_ptr+0)^ and $0101010101010101)<>0) then
    Writeln('arr[1] is not 0;')
  else
    Writeln('arr[1] is 0;');
  Readln;
end.
Output:
arr[0] is not 0; 
arr[1] is 0; // хотя выше мы установили 1;
var
  arr    : array of byte;
  arr_ptr: PByte;
  i      : integer;
begin
  SetLength(arr,8);
  arr_ptr:=@arr[0];
  arr[1]:=1;
  if (((arr_ptr+0)^ and $0101010101010101)<>0) then
    Writeln('arr[1] is not 0;')
  else
    Writeln('arr[1] is 0;');
  Readln;
end.
Output:
arr[1] is 0; // хотя выше мы установили 1;

Еще будут идеи?
P.S. винда 64-битная.

#66
7:25, 23 мая 2022

проверь что вообще в массиве лежит.

#67
(Правка: 7:33) 7:26, 23 мая 2022

  Пока что такое придумалось:

var
  arr              : array of byte;
  arr_ptr          : PByte;
  i                : integer;
  non_zero_item_pos: integer;
begin
  SetLength(arr,8);
  arr_ptr  :=@arr[0];
  arr[1]   :=1;
  if (PQWord(arr_ptr)^<>0) then
    begin
      for i:=0 to 7 do
        if ((arr_ptr+i)^<>0) then
          begin
            non_zero_item_pos:=i;
            Break;
          end;
      Writeln('arr[0] is not 0; non_zero_item_pos=',i,';');
    end
  else
    Writeln('arr[0] is 0;');
  Readln;
end.

То есть те же проверки блоков по 8 байт, но если нашлась цепочка, содержащая хоть один ненулевой байт, то дальше идет уточняющий поиск. Ну и конечно же надо отслеживать, чтоб проверка не вышла за границы массива(где будут возможно "мусорные" байты). Не знаю как оно будет по скорости, предполагаемо, что быстрее байтовых сдвигов с последующими проверками, но возможно несколько медленнее, чем IndexOfByte. Тут надо еще отдельный тест сделать.
  Также в процессе поиска решения наткнулся на весьма интересный хак .

#68
7:27, 23 мая 2022

Mirrel, в массиве нули, как и ожидается.

#69
(Правка: 7:42) 7:32, 23 мая 2022
function OnlyFans(const bt: array of byte; v: byte {the fan}): Boolean;
const
  m = ($FFFFFFFF div 255); // $01010101
var
  p : PDWORD;
  trg : longword;
  cnt : integer;
  i : integer;
begin
  trg := m * v;
  {$push POINTERMATH}
  {$POINTERMATH ON}
  p := @bt[0];
  cnt := length(bt) div 4;
  i := cnt * 4;
  while cnt>0 do begin
    Result := p^ = trg;
    // Result := (p^ xor trg) = 0;
    if not Result then Exit;
    inc(p);
    dec(cnt);
  end;
  Result := ( (i>=length(bt)) or (bt[i]=v))
          and ((i+1>=length(bt)) or (bt[i+1]=v))
          and ((i+2>=length(bt)) or (bt[i+2]=v));
  {$pop pointermath}
end;
#70
(Правка: 7:41) 7:39, 23 мая 2022

ArtProg
PQWord или PLongWord поставь. Это твоё решение.

if (((PQWord(arr_ptr+0)^) and $0101010101010101)<>0) then 

В противном случае он сравнивает байты, а ты не смещал байт для проверки.
И как я и думал, в массиве как раз единица лежит, там, куда ты её положил. )))

#71
7:41, 23 мая 2022

Mirrel
> ArtProg, PQWord поставь. Это твоё решение.
а если в arr_ptr будут $22448824 записаны? :)
то это тоже норм? нулями считается?

#72
7:42, 23 мая 2022

  Ага, спасибо! Сейчас проверю на работоспособность ;).

#73
7:44, 23 мая 2022

skalogryz
> а если в arr_ptr будут $22448824 записаны?
он хочет единицы проверить )))
По сути проверку двойную делать надо.

в твоём варианте вообще все нули выпадут )))

#74
7:47, 23 мая 2022

  Mirrel, да, мой огрех, все верно. Впрочем это уже исправлено в следующем примере.

Страницы: 14 5 6 756 Следующая »
ПрограммированиеФорумОбщее