Здравствуйте, rg45, Вы писали:
R>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
D>>>Задача: написать функцию f(x), так, что f(f(x))= -x. Разрешено использовать только
D>>>целые числа. x — целочисленный аргумент (например, 32-битный).
Здравствуйте, Панда, Вы писали:
П>Подумал. В целом — задача неразрешимая. Потому что есть такое 32-битное x, для которого невозможно записать 32 битами -x. Это число, у которого все биты 1.
П>Если это число выкинуть из допустимых аргументов — то придумал. П>Продемонстрирую идею такой функции, если x может принимать значения от -3 до 3. П>
Подумал. В целом — задача неразрешимая. Потому что есть такое 32-битное x, для которого невозможно записать 32 битами -x. Это число, у которого все биты 1.
Если это число выкинуть из допустимых аргументов — то придумал.
Продемонстрирую идею такой функции, если x может принимать значения от -3 до 3.
int f(int x)
{
int y[] = {0, 1, 2, 3, 0, -1, -2, -3};
return y[(x+2)%8];
}
D>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>целые числа. x — целочисленный аргумент (например, 32-битный).
int f(int x)
{
const unsigned int MAX = (1 << 31);
int order = x >= 0 ? x : -x + MAX;
order = (order + MAX/2);
if (order < MAX) return order;
else return -(order - MAX);
}
Кстати, можно сформулировать аналогичную задачу по математике, а не по программированию.
Найти функцию f, для которой f(f(x)) — -x
x — любое вещественное число без ограничений.
Такую функцию я тоже придумал, но пока не смог записать ее аналитически.
Здравствуйте, Vintik_69, Вы писали:
V_>Здравствуйте, RomikT, Вы писали:
RT>>Наверняка не самое короткое решение, но вроде работать будет.
V_>Не работает для 2147483647
По моему, несложно доказать что среди чисел от -2147483648 до 2147483647 невозможно давать правильный результат для всех чисел.
Как минимум, два числа окажутся неохваченными. Одно — просто потому, что нет числа +2147483648. А второе — ну так мир устроен
Здравствуйте, RomikT, Вы писали:
RT>Как минимум, два числа окажутся неохваченными. Одно — просто потому, что нет числа +2147483648. А второе — ну так мир устроен
Ну насчет второго — не понятно. У меня вроде для всех, кроме одного, работает.
Давайте тогда уж BigFloat — произвольные дробные с бесконечной точностью. Решение, которое приводил deniok, должно работать и для них. Только на even надо проверять не x, а round(abs(x)).
Здравствуйте, Roman Odaisky, Вы писали:
П>>Найти функцию f, для которой f(f(x)) — -x П>>x — любое вещественное число без ограничений.
RO>Делов-то...
RO>f(f(x)) = -x RO>f² = -1 RO>f = i RO>f(x) = ix
А какое вещественное число обозначено таинственной буквой i?
Здравствуйте, RomikT, Вы писали: RT>А какое вещественное число обозначено таинственной буквой i?
С комплексными тоже прикольно. Но для вещественных тоже строится элементарно. Я уже просек фишку. Нам надо разбить все положительные вещественные числа на непересекающиеся пары. Это можно сделать сотнями способов.
После этого строим функцию:
f(0) = 0
Для любой пары (x1, x2)
f(x1) = x2
f(x2) = -x1
f(-x1) = -x2
f(-x2) = x1
Re[3]: f(f(x)) = -x
От:
Аноним
Дата:
18.01.08 00:08
Оценка:
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
А>>Задача очевидно не имеет решения.
D>Для пуристов: снимаю ограничение на 32 бита. Допустимы произвольные целые — BigInteger.
Ну тогда решение простое: мы имеем 4 перестановки(тк уравнение 4 порядка), так что рассмотрим кольцо -2 -1 0 1 2.
0 преобразуется сам на себя, а из остальных чисел выбираем любой из 2 вариантов, например -2 -> 1, -1 -> -2, 1 -> 2, 2 -> -1.
Так что решение существует для любого множества кратного 4 + тривиальные числа, например 0.
Здравствуйте, RomikT, Вы писали:
RT>Здравствуйте, Vintik_69, Вы писали:
V_>>Здравствуйте, RomikT, Вы писали:
RT>>>Наверняка не самое короткое решение, но вроде работать будет.
V_>>Не работает для 2147483647
RT>По моему, несложно доказать что среди чисел от -2147483648 до 2147483647 невозможно давать правильный результат для всех чисел. RT>Как минимум, два числа окажутся неохваченными. Одно — просто потому, что нет числа +2147483648. А второе — ну так мир устроен
Здравствуйте, RomikT, Вы писали:
RT>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
RT>Наверняка не самое короткое решение, но вроде работать будет. RT>
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, deniok, Вы писали:
D>>
D>>Задача: написать функцию f(x), так, что f(f(x)) = -x. Разрешено использовать только
D>>целые числа. x — целочисленный аргумент (например, 32-битный).
struct othertype
{
int val;
int atr;
};
othertype f(int i)
{
othertype r;
r.val = i;
return r;
}
int f(othertype o)
{
return -o.val;
}
Re[2]: f(f(x)) = -x
От:
Аноним
Дата:
22.01.08 16:03
Оценка:
Здравствуйте, Панда, Вы писали:
П>Кстати, можно сформулировать аналогичную задачу по математике, а не по программированию. П>Найти функцию 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, например.