Здравствуйте, Панда, Вы писали:
П>Кстати, можно сформулировать аналогичную задачу по математике, а не по программированию. П>Найти функцию f, для которой f(f(x)) — -x П>x — любое вещественное число без ограничений. П>Такую функцию я тоже придумал, но пока не смог записать ее аналитически.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
в виде выдвигающегося/задвигающегося CD-ROM-а. В обоих случаях используется статическая переменная (в случае с CD-ROM -- hard static bool). Идея в том, что если между двумя последовательными вызовами что-то произойдет, ну, например, вы вызовите эту же функцию для другого аргумента из другого потока (или вручную задвините CD-ROM ), то все полетит.
Здравствуйте, yachmen, Вы писали:
Y>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
Здравствуйте, vadimcher, Вы писали:
V>f(f(0x80000001)) = 0x80000001
Прикольно — ведь я и проверял-то только -1, 0, 1, 0x7fffffff, 0x80000000 и 0x80000001 — но глаз замылился и не увидел это в логе
Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
Здравствуйте, Ячменников Александр, Вы писали:
ЯА>Здравствуйте, vadimcher, Вы писали:
V>>f(f(0x80000001)) = 0x80000001
ЯА>Прикольно — ведь я и проверял-то только -1, 0, 1, 0x7fffffff, 0x80000000 и 0x80000001 — но глаз замылился и не увидел это в логе ЯА>Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
ЯА>Всего наилучшего
Я бы даже сказал, можно для всех чисел, кроме одного.
Здравствуйте, vadimcher, Вы писали:
V>Здравствуйте, Ячменников Александр, Вы писали:
ЯА>>Здравствуйте, vadimcher, Вы писали:
V>>>f(f(0x80000001)) = 0x80000001
ЯА>>Прикольно — ведь я и проверял-то только -1, 0, 1, 0x7fffffff, 0x80000000 и 0x80000001 — но глаз замылился и не увидел это в логе ЯА>>Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
ЯА>>Всего наилучшего
V>Я бы даже сказал, можно для всех чисел, кроме одного.
Что, кстати, иллюстрирует необходимость покрытия кода тотальными тестами (или использования формальной верификации программы)
Здравствуйте, Ячменников Александр, Вы писали:
ЯА>Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
Ну это скорее следствие того, что для какого-то числа х нельзя вычислить -х...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Ячменников Александр, Вы писали:
ЯА>>Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
E>Ну это скорее следствие того, что для какого-то числа х нельзя вычислить -х...
Ну, в общем, да... Хотя, -x формально можно вычислить для любого числа: -0=0, -0x80000000=0x80000000. Просто для одного из них это будет математически неверное -x.
Но проблема здесь не в этом. Если a->b, то b->-a, и -a->-b->a. Т.е. если a!=-a, то требуются четверки чисел, а все такие числа, для которых a!=-a на четверки как раз и не делятся. Т.е. если бы таких чисел было число, кратное 4, то задача решалась бы.
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, vadimcher, Вы писали:
V>>Здравствуйте, Ячменников Александр, Вы писали:
ЯА>>>Здравствуйте, vadimcher, Вы писали:
V>>>>f(f(0x80000001)) = 0x80000001
ЯА>>>Прикольно — ведь я и проверял-то только -1, 0, 1, 0x7fffffff, 0x80000000 и 0x80000001 — но глаз замылился и не увидел это в логе ЯА>>>Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
ЯА>>>Всего наилучшего
V>>Я бы даже сказал, можно для всех чисел, кроме одного.
D>Что, кстати, иллюстрирует необходимость покрытия кода тотальными тестами (или использования формальной верификации программы)
Да уж... Я сразу вспоминаю недавний глюк Excel 2007, который "работал" только для 12 из 9.2*10^18 64-битных чисел с плавающей точкой.
Здравствуйте, vadimcher, Вы писали:
V>Ну, в общем, да... Хотя, -x формально можно вычислить для любого числа: -0=0, -0x80000000=0x80000000. Просто для одного из них это будет математически неверное -x.
Зависит от. Если используется прямой код, то -0x80000000=0x00000000, т.е -(-0)=0.
В обратном коде -0x80000000=0x7FFFFFFFF или -(-2147385345)=2147385345.
Здравствуйте, Ячменников Александр, Вы писали:
ЯА>Прикольно — ведь я и проверял-то только -1, 0, 1, 0x7fffffff, 0x80000000 и 0x80000001 — но глаз замылился и не увидел это в логе ЯА>Т.о. вывод такой — можно сделать эту функцию для всех чисел кроме двух, необязательно 0x80000000 и 0x80000001.
Ну, тут уже показывали, что для 32-битных целых (да и вообще для любых целых в двоичной сетке) это невозможно.
Дело в том, что все числа кроме 0 и INT_MIN (в дополнительном коде INT_MIN < -INT_MAX) группируются по 4:
{ x, y=f(x), -x=f(y), -y=f(-x) }, дальше будет x=f(-y)
Остаются 0 и INT_MIN, так что либо f(0)=0, f(INT_MIN)=INT_MIN, либо f(0)=INT_MIN, f(INT_MIN)=0.
Итого, мощность множества целых чисел равна 4n+2. А на самом деле — 2^p.
А в прямом коде, где -0 и 0 — это разные числа, и они не выпадают из общего правила f(f(x))=-x, f(f(0))=-0, — решение есть.
Произвольным образом разбиваем множество Z+ неотрицательных чисел на два равномощных подмножества A+, B+ и строим f как колечки: A+ -> B+ -> A- -> B-.
В качестве способа разбиения проще всего предложить чётность.
То же касается неограниченных целых чисел, и для вещественных. Там есть единственное особое число 0, и для него f(0)=0. А все остальные так же группируются.
У вещественных можно разбивать по признаку frac(x) < / >= 0.5, например.