Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / FAQ / Обмен значений переменных.

Обмен значений переменных.

Замена классического варианта (с на d)

a c, d;
...
a b = c;
c = d;
d = b;
Вариант с суммой:
a c, d; // a - арифметический тип
...
с = с + d;
d = с - d;
с = с - d;
Вариант без использования дополнительной переменной:
Пусть нужно обменять a и b (a, b - арифметический тип)
a += b;
b = a - b;
a -= b;
Вариант с операцией исключающего или (XOR) (Делать по области памяти)
a c, d; // a - целый тип, или юзать reinterpret_cast
...
c ^= d;
d ^= c;
c ^= d;
В ассемблере Intel- AMD- совместимых процессоров есть комманда XCHG, меняющая значения своих операндов.
XCHG c, d
Примечание: "Инструкция 'XCHG регистр, [память]' опасна. По умолчанию эта инструкция имеет неявный префикс LOCK, что не дает ей загружаться в кэш. Поэтому выполнение данной инструкции отнимает очень много времени, и ее следует избегать."
(C) Агнер Фог, пер. Aquila - Оптимизация для процессоров семейства Pentium  источник: http://wasm.ru/article.php?article=1010027

Ссылка на тему обсуждения: http://www.gamedev.ru/flame/forum/?id=77859

14 марта 2008


Обновление: 10 июня 2009

Комментарии:

Страницы: 1 2 3 4 5 Следующая

4mlrПостоялецwww10 июня 20091:15#1
Вариант с суммой:

a c, d; // a - арифметический тип
...
с = с + d;
d = с - d;
с = с - d;


Вариант без использования дополнительной переменной:
Пусть нужно обменять a и b (a, b - арифметический тип)

a += b;
b = a - b;
a -= b;

А разве это не одно и тоже написано?

KlounПостоялецwww10 июня 20092:55#2
4mlr
> А разве это не одно и тоже написано?
xDD )))) ну очевидно же что да! )))) там с d, а тут a b
4mlrПостоялецwww11 июня 200917:38#3
Kloun
> 4mlr
> > А разве это не одно и тоже написано?
> xDD )))) ну очевидно же что да! )))) там с d, а тут a b
А зачем тогда в статье два раза одно и тоже писать? щ_Щ
KlounПостоялецwww11 июня 200921:15#4
4mlr
как зачем? чтобы больше вариантов было! а то былаб подсказкочка коротенькая.
NULL_PTRПостоялецwww12 июня 20091:02#5
Kloun
> а то былаб подсказкочка коротенькая.
Это faq.
KlounПостоялецwww12 июня 20091:25#6
NULL_PTR
> Это faq
действительно... а по смыслу подсказка.... я чет такими вопросами не задовался ни разу, и чудиться мне что на "часто задоваемый" этот вопрос не тянет.
murderПостоялецwww12 июня 20097:29#7
a:=a xor b;
b:=a xor b;
a:=a xor b;
hellokoteПользовательwww12 июня 20099:17#8
Для a != 0 и b != 0:
a = a * b; 
b = a / b; 
a = a / b;

Для a > 0 и b > 0:

a = power(a, b);
b = power(a, 1/b);
a = log(a, b);

=D

Alex the..Новичокwww4 апр. 201115:06#9
реализуя предложенные вами алгоритмы обмена двух чисел без доп переменной
на языке turbo pascal 7.0 и в дальнейшем в отладчике td.exe обнаружил примерно следующие два кода (два алгоритма)  (в фигурных скобках мои комментарии)

{a:=a+b}
  mov bx, [0053]
  mov ax, [0052]
  add ax, bx
{b:=a-b} 
  sub ax,bx
  mov [0053],ax
{a:=a-b}
  mov ax, [0052]
  sub ax, bx
  mov [0052], ax

-----------------------------------------------------------------
{a : = a xor b}
  mov al, [0001]
  xor  al, [0002]
  mov [0001], al
{b : = a xor b}
  mov al, [0002]
  mov [0002],al
{a : =a xor b}
  mov al,[0001]
  xor al, [0002]
  mov [0001],al

то есть на низком уровне происходит использование до двух регистров и по мере их затирания, они восстанавливаются из операндов памяти, а это уже нарушение условий задачи

я сомневаюсь, что другие компиляторы делают по другому

более того неплохо бы разобраться в работе команд процессора изнутри, на уровне элементарных логических функций.

вот например команда процессора сложить
add ax, bx {ax:=ax+bx}

при этом в самом ли деле процесс сложения связан с процессом плавного затирания уже не используемых битов регистра ax?
или все таки с использованием дополнительного скрытого от всех регистра?


единственное что работает прекрасно это ..
mov ax, [0001]
mov dx, [0002]
xchg ax, dx

всего в два- четыре такта и три строки

MATovУчастникwww4 апр. 201116:19#10
std::swap и пофик)
gammakerПостоялецwww4 апр. 201118:36#11
Я раньше использовал вариант с XOR, но оказалось, он работает медленнее, чем с временной переменной. Лучше использовать временную переменную. Другие варианты не пробовал, но думаю, что будет ещё дольше. Я думаю, что в этих вариантах нет смысла: они делают код непонятным и замедляют программу.
KpeHDeJIbПостоялецwww4 апр. 201118:38#12
Alex the..
> единственное что работает прекрасно это ..
Это обмен значений двух регистров, а не двух переменных ЯВУ. Ну и приводить результаты какого-то конкретного компилятора это кхм, приводи тогда уж сразу результаты 5-6 компиляторов.
Alex the..Новичокwww4 апр. 201120:32#13
>KpeHDeJIb
>приводи тогда уж сразу результаты 5-6 компиляторов.

назовите какой нибудь низкоуровневый компилятор, код которого бы не восстанавливал значения регистров из памяти в процессе работы

все может быть, ..
, но паскалевский считался когда то эталонным
и с тех пор компиляторы только разжирели


да и вопрос тут ставиться, возможно ли это в принципе?
и каков механизм внутренней работы низкоуровневых команд процессора?

shekhПостоялецwww4 апр. 201122:17#14
Вот прицепились к этому ксору. Его учат на информатике в школе потому что через него можно реализовать какую-то операцию *в железе*, не используя никаких лишних битов под буфер. В программировании использовать - ни малейшего смысла.

Страницы: 1 2 3 4 5 Следующая

/ Форум / Программирование игр / Общее

Тема в архиве.

2001—2017 © GameDev.ru — Разработка игр