| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Обмен значениями между переменными |
| Автор: val 12.11.2003, 18:16 | ||||
| Способ, как обменяться значениями между двумя переменными, не используя третей, т.е. 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 - великая вещь! |
| Автор: maxim1000 12.11.2003, 19:22 | ||
это будет работать даже, если будут возникать переполнения (оно, ведь, действует в две стороны) |
| Автор: 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 | ||
вот это как раз не совсем пройдет: в компьютерах не всегда (x/y)*y=x |
| Автор: val 14.11.2003, 11:33 | ||
Для PC - вполне... |
| Автор: maxim1000 14.11.2003, 11:49 | ||
а на PC уже отменили целочисленный тип? |
| Автор: shedon 14.11.2003, 12:06 | ||||
В итоге х=4!!! 5 делится на 2, получается 2,5, но т.к. тип int то получаем 2, 2 умножаем на 2 получаем 4!!! |
| Автор: val 14.11.2003, 13:24 | ||
да, забыл добавить, что необходимо учитывать и такие ньансы... Но есть конкретное тождество 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 | ||||
Будет. НЕльзя сравнивать вещественные числа, поэтому и тождества не будет.
Этот код чаще будет выдавать "Нет". |
| Автор: Waters 16.11.2003, 07:50 | ||
И насколько часто? Один раз на два, на сто или на тысячу запусков? wbr. |
| Автор: val 17.11.2003, 11:53 | ||||||
Проверил на Visual C++.NET циклом 1 000 000 раз - всегда только "Да". Так что Вы, товарищ, gray_k, в чем-то не совсем точны... |
| Автор: shedon 17.11.2003, 12:20 | ||||
gray_k, прав нельзя сравнивать, на равенство, числа с плавоющей точкой!!! А код
Будет выдавать да не при всех значениях |
| Автор: gray_k 17.11.2003, 13:16 |
| Просто этот пример очень упрощённый. Поэтому и срабатывает. А в том примере нельзя дать гранитию, что условие выполнится всегда. Это связано с физическим хранением чисел с плавающей точкой в памяти. Я, например, видел как в одной программе была сделана такая проверка - считалась сумма по выборке из БД, затем пользователю предлагалось ввести эту сумму (из документа) в Edit. После этого поисходило сравнение. Так вот пользователи очень удивлялись, когда на мониторе показывалось сообщение об ошибке, хотя визуально цифры были абсолютно равны. Вот так. |
| Автор: 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 можно написать так:
при использовании третьего регистра тоже будет три команды, но довольно часто бывает нужна экономия в регистрах, поэтому такое решение может оказаться полезным теперь C: попробовал: оказалось, что традиционным способом все-таки быстрее... |
| Автор: GanZaleZ 19.11.2003, 23:08 |
| В XORе больше машинных команд нежели то делать с 3 переменными ! поэтому лучше с 3 переменными , тобш с командой пресваивания |
| Автор: maxim1000 20.11.2003, 11:33 | ||
это зависит от процессора и от памяти, в которой хранятся переменные |
| Автор: 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 переменные Самы оптимальный фариант и код понятен будет даже через 3 года |