Ознакомьтесь в файле помощь Delphi с функцией Swap. Но там в
определении есть опечатка, правильно будет так:
Ниже приведен пример использования:
|
|
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 - направо). |