Ну, вот быстрый взлом C:
extern double f(double x);
double g(double x)
{
static int parity = 0;
parity ^= 1;
return (parity ? x : f(x));
}
Однако, это сломается, если вы сделаете:
a = g(4.0); // => a = 4.0, parity = 1
b = g(2.0); // => b = f(2.0), parity = 0
c = g(a); // => c = 4.0, parity = 1
d = g(b); // => d = f(f(2.0)), parity = 0
В общем случае, если f - биекция f: D & rarr; D, вам нужна функция & sigma; который разделяет домен D на A и B так, что:
- D = A & cup; Б (раздел тотальный)
- & пусто; = A & cap; B (раздел не пересекается)
- & sigma; (a) & isin; B, f (a) & isin; A & forall; & isin; A
- & sigma; b) & isin; A, f (b) & isin; B & Forall; b & isin; B
- & Sigma; имеет обратную & sigma; -1 s.t. & sigma; (& sigma; -1 (d)) = & sigma; -1 (& sigma; (d)) = d & forall; д & исин; D.
- & sigma; (f (d)) = f (& sigma; (d)) & forall; д & исин; D
Затем вы можете определить g следующим образом:
- g (a) = & sigma; (f (a)) & forall; & isin; A
- g (b) = & sigma; -1 (b) & forall; b & isin; B
Это работает б / с
- & FORALL; & isin; A, g (g (a)) = g (& sigma; (f (a)). Согласно (3), f (a) & isin; A so & sigma; (f (a)) & isin; B so g (& sigma; (f (a)) = & sigma; -1 (& sigma; (f (a))) = f (a).
Из ответа Майлза видно, что если мы игнорируем 0, то операция & sigma; (x) = -x работает для f (x) = 1 / x. Вы можете проверить 1-6 (для D = ненулевые вещественные числа), где A - положительные числа, а B - отрицательные числа. В стандарте двойной точности есть +0
, -0
, a +inf
и -inf
, и они могут быть использованы для получения общего значения домена (применимо ко всем числам двойной точности, а не только к ненулевым ).
Тот же самый метод может быть применен к проблеме f (x) = -1 - принятое решение там разделяет пространство на оставшуюся часть mod 2, используя & sigma; (x) = (x - 1), обрабатывая нулевой случай специально.