Письма читателей 24

Я конечно думал, что заметка про обмен значений переменных вызовет некоторое количество замечаний, но в таком объёме...;[]

From: Andy Ice <AndyIce@mail.ru>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 11:32:19 AM
Subject: Олимпиадные задачи с решениями на Turbo Pascal

Хотелось бы предостеречь от явной ошибки в данном алгоритме. Дело в том, информатика - это, все таки, не "чистая математика", и возможно сразу же в первой строчке получить ошибку переполнения.

Пример:
a, b: Byte;
a0 := 250;
b0 := 200;

Результат?

From: Andrew Ezhguroff <eandr@com2com.ru>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 11:29:42 AM
Subject:
Обмен значений переменных

Здравствуйте.

Если в языке возможны битовые операции с целыми числами (не знаю, есть ли это в TP), то subj можно записать забавнее:

a:=a xor b; {a=a0^b0, b=b0}
b:=a xor b; {a=a0^b0, b=a0^b0^b0=a0}
a:=a xor b; {a=a0^b0^a0=b0, b=a0}

С уважением, Андрей.

From: zugr <zugr@unikon-ua.net>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 2:10:18 PM
Subject:
Обмен значений переменных

А на С это ищё красивее:

a^=b;
b^=a;
a^=b;

:-)

From: Boris Bukh <brbukh@yahoo.com>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 6:20:58 PM
Subject: Неточность в теории

Hello,

В последней рассылке неточность в разделе теория. Если использовать +,- то тогда если нечайно откомпилировать прогу с проверкой переполнения, то тогда можете получить run-time error в самый неприятный момент. Лучше пользоваться xor.

a:=a xor b; {a=a0 xor b0 }
b:=a xor b; {b=a0}
a:=a xor b; {a=b0}

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

From: Serhiy Serbin <serhiys@adarvo.com>
To: sapisoft@yandex.ru
Date: Friday, March 15, 2002, 9:32:38 AM
Subject: Обмен значений переменных

Привет, то что придумали давно не спорю :)) Но знать должен каждый :)) Есть еще один вариант, по идее должен роботать быстрее:

a = a ^ b;
b = a ^ b;
a = b ^ a;

, где = - оператор присваивания, а ^ - xor. К сожалению Паскакаль не знаю, так что в его нотации записать не могу.

Best regards,
Serhiy Serbin

From: Alex <malex@ua.fm>
To: sapisoft@yandex.ru
Date: Friday, March 15, 2002, 2:45:38 PM
Subject:
Обмен значений переменных

Hi!

хорошая рассылка! только imho: 1 - мало:(, 2 - только самые известные проблемы!

в рассылке от 11.03.2002 был известный пример Сабжа от HellMan

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
procedure swap(var a, b: char);
begin
if a = b then
exit;
byte(a) := byte(a) xor byte(b);
byte(b) := byte(a) xor byte(b);
byte(a) := byte(a) xor byte(b);
end;
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==

дык этот обмен имеет несложное продолжение на циклический сдвиг n переменных:

procedure rotR(var x1, x2, ...., xn: longint)
;
begin
x1:= x1 xor x2 xor x3 xor ..... xor xn;
x2:= x1 xor x2 xor x3 xor ..... xor xn;
x3:= x1 xor x2 xor x3 xor ..... xor xn;
.....
xn:= x1 xor x2 xor x3 xor ..... xor xn;
x1:= x1 xor x2 xor x3 xor ..... xor xn;
end;

зы: ну и далее можно развивать экстенсивно....

ззыы: в частности можно любую !ИЗВЕСТНУЮ! (!) перестановку n чисел реализовать - за n+1 строчку!

Gby! Gby! See you later...

From: Алексей Ильичёв <alex_z77@mail.ru>
To: sapisoft@yandex.ru
Date: Saturday, March 16, 2002, 6:37:40 AM
Subject: Теоретическая часть: обмен значений переменных

Здравствуйте, Алексей.

Хотелось бы прокомментировать хитрость, которую вы продемонстрировали в теоретическом разделе выпуска 23.

Есть практически аналогичный способ, обеспечивающий нам полную устойчивость. Оператор A := A + B; может выполниться с ошибкой, т.к. никто нам не гарантирует, что размер переменной A позволяет хранить значение суммы A + B. Чтобы избежать такого маленького недоразумения, как переполнение, можно тот же приём проделать через XOR-сумму. Например так:

A := A xor B; {A = a0 xor b0}
B := A xor B; {B = a0 xor b0 xor b0 = a0}
A := A xor B; {A = a0 xor b0 xor a0 = b0}

Ещё хотелось бы предостеречь читателей от типичной ошибки:

Procedure Swap(Var A, B : Integer);
begin
A := A xor B;
B := A xor
B;
A := A xor B;
end;

Если такой процедурке задать в качестве параметров одну и ту же переменную, она обнулиться. Т.к. получится, что A и B - это одна и та же переменная, а как известно A xor B = 0. То есть если вы пишите алгоритм, в котором вы не застрахованны от подобного вызова, лучше не жадничать, и выделить лишних несколько байт для обмена через 3-ю переменную. (эта ошибка касается так же обмена через сумму).

Алексей Шамис: От себя хочу добавить, что на существование имеет право любой из представленых алгоритмов, просто каждый из них имеет те или иные ограничения. Начинающему легче понять первый вариант решения задачи, а "продвинутые" программисты могут использовать функцию XOR для сложения чисел. В любом случае, спасибо за активность!

Я конечно думал, что заметка про обмен значений переменных вызовет некоторое количество замечаний, но в таком объёме...;[]

From: Andy Ice <AndyIce@mail.ru>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 11:32:19 AM
Subject: Олимпиадные задачи с решениями на Turbo Pascal

Хотелось бы предостеречь от явной ошибки в данном алгоритме. Дело в том, информатика - это, все таки, не "чистая математика", и возможно сразу же в первой строчке получить ошибку переполнения.

Пример:
a, b: Byte;
a0 := 250;
b0 := 200;

Результат?

From: Andrew Ezhguroff <eandr@com2com.ru>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 11:29:42 AM
Subject: Обмен значений переменных

Здравствуйте.

Если в языке возможны битовые операции с целыми числами (не знаю, есть ли это в TP), то subj можно записать забавнее:

a:=a xor b; {a=a0^b0, b=b0}
b:=a xor b; {a=a0^b0, b=a0^b0^b0=a0}
a:=a xor b; {a=a0^b0^a0=b0, b=a0}

С уважением, Андрей.

From: zugr <zugr@unikon-ua.net>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 2:10:18 PM
Subject: Обмен значений переменных

А на С это ищё красивее:

a^=b;
b^=a;
a^=b;


:-)

From: Boris Bukh <brbukh@yahoo.com>
To: sapisoft@yandex.ru
Date: Thursday, March 14, 2002, 6:20:58 PM
Subject: Неточность в теории

Hello,

В последней рассылке неточность в разделе теория. Если использовать +,- то тогда если нечайно откомпилировать прогу с проверкой переполнения, то тогда можете получить run-time error в самый неприятный момент. Лучше пользоваться xor.

a:=a xor b; {a=a0 xor b0 }
b:=a xor b; {b=a0}
a:=a xor b; {a=b0}

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