Обмен значений двух переменных без использования буфера

Это небольшая зарядка для ума, суть которой в следующем:

Нужно изменить всем известный код обмена значений двух переменных, типа

int a,b;
int buf=a;
a=b;
b=buf;

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

Те, кому лень думать самим, могут подсмотреть ответ чуть ниже, под картинкой. Но я бы рекомендовал попробовать догадаться без подсказки. Поэтому, пока вы думаете, можете полюбоваться на красивую картинку…

А теперь, барабанная дробь… Правильный ответ:

int a,b;
a = a + b;
b = a - b;
a = a - b;

Для тех, кто не верит, приведу таблицу, в которой в соответствующих колонках будут отображены значение, хранимые в обоих переменных после каждой операции:

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

В принципе, такой же способ можно использовать и для вещественных чисел. Однако, тут появляется одна проблема: потеря точности. Если нужно будет обменять местами очень малое значение с очень большим, то при a+b результат будет равен большему числу, т.к. малое относительно него будет приравнено к 0.

Для обмена значений вещественных переменных по той же схеме без риска потери точности можно использовать операцию «исключающего ИЛИ», или по-другому XOR. В С++ она обозначается «крышечкой» — ^. Т.е. итоговый код по обмену будет выглядеть так:

int a,b;
a = a ^ b;
b = a ^ b;
a = a ^ b;<

P.S.: Конечно, особого выигрыша от экономии нескольких байт памяти не будет, но, как было сказано выше, это неплохая зарядка для ума. И кто знает, вдруг и это когда-нибудь пригодится ;)

Полезная статья? Их будет больше, если вы поддержите меня!

https://money.yandex.ru/embed/small.xml?account=410011399843532&quickpay=small&yamoney-payment-type=on&button-text=06&button-size=l&button-color=orange&targets=%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%B2%D0%B0%D1%8E+%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82+lexpenz.com&default-sum=50&successURL=

Архив комментариев

2 комментария из прежней версии блога. Архив закрыт для новых ответов.

  1. Занимательная статья :)
    Было бы интересно почитать побольше о таких задачках и не стандартных ситуациях и решениях их в С/С++

  2. Rosskyавтор

    Спасибо :) Поищу в закромах еще что-нибудь подобное :)