Меню сайта
Мини-чат
Чтобы добавить сообщение, необходимо авторизоваться.
Главная » Статьи » Не стандартные примеры на Delphi » Алгоритмы

Байтовый своппинг
Ознакомьтесь в файле помощь Delphi с функцией Swap. Но там в определении есть опечатка, правильно будет так:


   
function Swap(X) : word;

Ниже приведен пример использования:


    var
X: Word;
begin
X := Swap($1234);   { $3412 }
end;

на первый взгляд ничего сложного.

Для своппинга 16-битного целого или слова, используйте следующий код:


   
value: integer;
value := swap(value); {внутренняя паскалевская функция}

Для свапирования 32-битного длинного целого:


   
value: longint;
value := swap(value shr 16) or (longint(swap(value and $ffff)) shl 16);

Я не знаю какие стандарты используются для значений с плавающей точкой, но если они соответствуют типам integer и longint (это моя догадка), то можно воспользоваться следующим кодом (для double):


   
value: double;
block: array[0..7] of byte absolute value;
temp:  byte;

for i := 0 to 3 do begin
temp := block[i];
block[i] := block[7-i];
block[7-i] := temp;
end;

При использовании типа real массив должен быть 0..5 и цикл от 0 до 2; при использовании типа comp, 0..7 и от 0 до 3; для single 0..3 и от 0 до 1; для extended 0..9 и от 0 дo 4.

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


   
procedure swapper (valin: pointer; size: integer);
var
i: integer;
temp: byte;
val:  ^byte;
begin
size := size - 1;
val := valin;
for i := 0 to (size div 2) do begin
temp := val[i];
val[i] := val[size-i];
val[size-i] := temp;
end;
end;

и затем так использовать это:


   
swapper (@value, sizeof(value));

(Это должно работать для longint, integer и пр., но swap() более эффективен.)

Обратите внимание на то, что дополнительно к своппингу байтов, вы можете делать преобразование формата (например, из Microsoft floating point в ANSI); я не знаком глубоко с темой чисел с плавающей точкой, поэтому эту тему я опущу. Качественной проверкой может служить сдиг байтов и проверку получившегося значения на другой системе, признающей формат чисел, обрабатываемый Delphi.

...у меня была аналогичная проблема: я считывал с диска TColor в формате RGB ($RRGGBB), тогда как delphi пользуется форматом BGR.

Я решил свою проблему and'ингом начального числа с маской, извлекая этим необходимые значения и "устанавливая" их в мой формат. Вот так:


    color := $F03200;
r := (color and $FF0000) div $010000; {должно возвратить $F0}
g := (color and $00FF00) div $000100; {должно возвратить $32}
b := (color and $0000FF);             {должно возвратить $00}
newcolor := (b * $010000) + (g * $000100) + b;

Если это сработает, то newcolor должен содержать $0032F0.

Вы можете использовать процедуру, написанную на языке ассемблер. Например, такую:


    var
result : byte;

asm {
mov cx,8
mov ah,0
mov al,<БАЙТ В ФОРМАТ BIG ENDIAN FORMAT>
@do_loop
shr al,1
shl ah,1
jcc @dont_set_bit  ; просто осуществляем переход (правда, я не уверен что это правильно)
xor ah,1
@dont_set_bit:
loop do_loop
mov result,al
}

Это скорее псевдо-код (поскольку мой ассемблер сильно хромает). Если вы хотите, чтобы код был более "портативным", то воспользуйтесь вместо inline-ассемблера паскалем (где можно использовать SHL - смещения бит налево и SHR - направо).

Категория: Алгоритмы | Добавил: DelphiAiX (28.04.2012)
Просмотров: 1111 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]