Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Обмен значениями между переменными


Автор: val 12.11.2003, 18:16
Способ, как обменяться значениями между двумя переменными, не используя третей,
т.е. a<-->b вместо
Код

z = a;
a = b;
b = z;

можно сделать:
Код

a^=b^=a^=b;

У кого какие соображения как всё это работает?

Автор: val 12.11.2003, 18:18
Да, это все работает...

Автор: gray_k 12.11.2003, 18:28
Это можно переписать так (справа налево):
a=a^b;
b=b^a;
a=a^b;
Если посмотришь то по поосле этого a и b поменяются значениями.
a0 - начальное значение a;
b0 - начальное значение b;
a=a0^b0;
b=b0^a=b0^(a0^b0)=a0;
a=a^b = (a0^b0)^a0 = b0;

Автор: Nastya 12.11.2003, 18:50
Если переменные не большые и не будет переполнения типа, то можно
int a,b;
a+=b;
b=a-b;
a=a-b;

Автор: Ars 12.11.2003, 19:10
XOR - великая вещь! biggrin.gif biggrin.gif biggrin.gif

Автор: maxim1000 12.11.2003, 19:22
Цитата
Если переменные не большые и не будет переполнения типа, то можно
int a,b;
a+=b;
b=a-b;
a=a-b;

это будет работать даже, если будут возникать переполнения (оно, ведь, действует в две стороны)

Автор: val 14.11.2003, 10:34
Обобщим ситуацию...
Пусть заданы две операции: F1: R^2 -> R, F2: R^2 -> R. Пусть также F2( F1( x, y), y) = x, F2( F1(x, y), x) = y.

Заданы начальные значения переменных:

x = x0,
y = y0

Выполним такие операции:

x <- F1(x, y) = F1(x0, y0)
y <- F2(x, y) = F2( F1(x0, y0), y0) = x0
x <- F2(x, y) = F2( F1(x0, y0), x0) = y0

Таким образом, мы поменяли местами значения переменных.

Мы уже знаем следующие возможности задания F1, F2:

1. F1(x, y) = F2(x, y) = x ^ y
2. F1(x, y) = x + y; F2(x, y) = x - y;

Можно в принципе придумать и другие способы по этому шаблону, например F1(x, y) = x * y, F2(x, y) = x / y.


Автор: maxim1000 14.11.2003, 11:26
Цитата
Можно в принципе придумать и другие способы по этому шаблону, например F1(x, y) = x * y, F2(x, y) = x / y.

вот это как раз не совсем пройдет: в компьютерах не всегда (x/y)*y=x

Автор: val 14.11.2003, 11:33
Цитата
вот это как раз не совсем пройдет: в компьютерах не всегда (x/y)*y=x


Для PC - вполне...

Автор: maxim1000 14.11.2003, 11:49
Цитата
Для PC - вполне...

а на PC уже отменили целочисленный тип?

Автор: shedon 14.11.2003, 12:06
Цитата
а на PC уже отменили целочисленный тип?

Код

int x,y;
x = 5;
y = 2;
x = (x/y)*y;

В итоге х=4!!!
5 делится на 2, получается 2,5, но т.к. тип int то получаем 2,
2 умножаем на 2 получаем 4!!!

Автор: val 14.11.2003, 13:24
Цитата
а на PC уже отменили целочисленный тип?

да, забыл добавить, что необходимо учитывать и такие ньансы...
Но есть конкретное тождество F2( F1( x, y), y) = x, F2( F1(x, y), x) = y, вот и смотрите, какие типы надо выбирать, чтобы оно выполнялось...

Автор: val 14.11.2003, 13:25
Возьмите типdouble и проблем не будет...

Автор: gray_k 14.11.2003, 13:36
Цитата
Возьмите типdouble и проблем не будет...

Будет.
НЕльзя сравнивать вещественные числа, поэтому и тождества не будет.
Код

double x1=0,1263748;
double x2;
x2=x1;
if(x1 == x2)
 ShowMessage("Да");
else
 ShowMessage("Нет");

Этот код чаще будет выдавать "Нет".

Автор: Waters 16.11.2003, 07:50
Цитата

double x1=0,1263748;
double x2;
x2=x1;
if(x1 == x2)
ShowMessage("Да");
else
ShowMessage("Нет");

Этот код чаще будет выдавать "Нет".


И насколько часто?

Один раз на два, на сто или на тысячу запусков? smile.gif

wbr.

Автор: val 17.11.2003, 11:53
Цитата
НЕльзя сравнивать вещественные числа, поэтому и тождества не будет.


Цитата

double x1=0,1263748;
double x2;
x2=x1;
if(x1 == x2)
ShowMessage("Да");
else
ShowMessage("Нет");


Цитата
Этот код чаще будет выдавать "Нет".


Проверил на Visual C++.NET циклом 1 000 000 раз - всегда только "Да". Так что Вы, товарищ, gray_k, в чем-то не совсем точны...

Автор: shedon 17.11.2003, 12:20
Цитата

Проверил на Visual C++.NET циклом 1 000 000 раз - всегда только "Да". Так что Вы, товарищ, gray_k, в чем-то не совсем точны...

gray_k, прав нельзя сравнивать, на равенство, числа с плавоющей точкой!!!
А код
Цитата

QUOTE 

double x1=0,1263748;
double x2;
x2=x1;
if(x1 == x2)
ShowMessage("Да");
else
ShowMessage("Нет");



Будет выдавать да не при всех значениях

Автор: gray_k 17.11.2003, 13:16
Просто этот пример очень упрощённый. Поэтому и срабатывает. А в том примере нельзя дать гранитию, что условие выполнится всегда. Это связано с физическим хранением чисел с плавающей точкой в памяти.
Я, например, видел как в одной программе была сделана такая проверка - считалась сумма по выборке из БД, затем пользователю предлагалось ввести эту сумму (из документа) в Edit. После этого поисходило сравнение. Так вот пользователи очень удивлялись, когда на мониторе показывалось сообщение об ошибке, хотя визуально цифры были абсолютно равны.
Вот так.smile.gif

Автор: val 17.11.2003, 13:37
Ладно, уговорили, но всё это как-то странно... Хорошо, буду учитывать в своих программах... Всем спасибо...

Автор: neutrino 17.11.2003, 14:15
а ксор работает быстрее, чем через третью переменную?

Автор: Ars 17.11.2003, 14:40
Цитата
а ксор работает быстрее, чем через третью переменную?

Медленнее, т.к. кроме операций записи в память присутствует сам XOR

Автор: maxim1000 17.11.2003, 15:15
Цитата
а ксор работает быстрее, чем через третью переменную?

думаю, это зависит от процессора
например, на ассемблере DSP BlackFin можно написать так:
Код
r0=r0^r1;
r1=r0^r1;
r0=r0^r1;

при использовании третьего регистра тоже будет три команды, но довольно часто бывает нужна экономия в регистрах, поэтому такое решение может оказаться полезным
теперь C: попробовал: оказалось, что традиционным способом все-таки быстрее...

Автор: GanZaleZ 19.11.2003, 23:08
В XORе больше машинных команд нежели то делать с 3 переменными !
поэтому лучше с 3 переменными , тобш с командой пресваивания smile.gif

Автор: maxim1000 20.11.2003, 11:33
Цитата
В XORе больше машинных команд нежели то делать с 3 переменными !
поэтому лучше с 3 переменными , тобш с командой пресваивания

это зависит от процессора и от памяти, в которой хранятся переменные

Автор: val 20.11.2003, 13:20
Цитата
это зависит от процессора

maxim1000 абсолютно прав...
На сегодняшний день вычислительный процесс можно организовать таким образом, чтобы выборка из памяти операндов и выполнения некоторых операций над ними проходили за один машинный такт.
Цитата
и от памяти

В некоторых проектах для хранения переменных, массивов используется SRAM-память, выборка слов из которой происходит за один такт, как из регистров!

Автор: val 20.11.2003, 13:22
Да, что-то нас в сферу специализированных вычислительных средств занесло... И все из-за того, что ANSI C - кроссплатформенный стандарт...

Автор: maxim1000 20.11.2003, 13:44
Цитата
Да, что-то нас в сферу специализированных вычислительных средств занесло...

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

Автор: GanZaleZ 20.11.2003, 22:31
Ну фощем нужно использофать 3 переменные smile.gif
Самы оптимальный фариант и код понятен будет даже через 3 года smile.gif ато потом фспоминай че ты там ксорил ксерил и тд .. smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)