Войти
Программирование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)

Комментарии [60]

Страницы: 1 2 3 4 5 Следующая »
#1
1:15, 10 июня 2009

Вариант с суммой:

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


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

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

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

#2
2:55, 10 июня 2009

4mlr
> А разве это не одно и тоже написано?
xDD )))) ну очевидно же что да! )))) там с d, а тут a b

#3
17:38, 11 июня 2009

Kloun
> 4mlr
> > А разве это не одно и тоже написано?
> xDD )))) ну очевидно же что да! )))) там с d, а тут a b
А зачем тогда в статье два раза одно и тоже писать? щ_Щ

#4
21:15, 11 июня 2009

4mlr
как зачем? чтобы больше вариантов было! а то былаб подсказкочка коротенькая.

#5
1:02, 12 июня 2009

Kloun
> а то былаб подсказкочка коротенькая.
Это faq.

#6
1:25, 12 июня 2009

NULL_PTR
> Это faq
действительно... а по смыслу подсказка.... я чет такими вопросами не задовался ни разу, и чудиться мне что на "часто задоваемый" этот вопрос не тянет.

#7
7:29, 12 июня 2009

a:=a xor b;
b:=a xor b;
a:=a xor b;

#8
9:17, 12 июня 2009

Для 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

Прошло более 1 года
#9
15:06, 4 апр 2011

реализуя предложенные вами алгоритмы обмена двух чисел без доп переменной
на языке 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

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

#10
16:19, 4 апр 2011

std::swap и пофик)

#11
18:36, 4 апр 2011

Я раньше использовал вариант с XOR, но оказалось, он работает медленнее, чем с временной переменной. Лучше использовать временную переменную. Другие варианты не пробовал, но думаю, что будет ещё дольше. Я думаю, что в этих вариантах нет смысла: они делают код непонятным и замедляют программу.

#12
18:38, 4 апр 2011

Alex the..
> единственное что работает прекрасно это ..
Это обмен значений двух регистров, а не двух переменных ЯВУ. Ну и приводить результаты какого-то конкретного компилятора это кхм, приводи тогда уж сразу результаты 5-6 компиляторов.

#13
20:32, 4 апр 2011

>KpeHDeJIb
>приводи тогда уж сразу результаты 5-6 компиляторов.

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

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


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

#14
22:17, 4 апр 2011

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

Страницы: 1 2 3 4 5 Следующая »
ПрограммированиеFAQОбщее

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