f(f(x)) = -x

f(f(x)) ==> -x な、実数を返す f を定義せよ…クイズ - Smalltalkのtは小文字です経由で。
流行っているようなので。やっぱり C でやってみた。場合分けが多いのを恐れない。

2 回適用すると元の値の符号を反転した値が返るような,実数から実数への関数 f を定義せよ.

f (f (x)) = -x
double f(double x) {
  static double flag = 0.0;
  double UP = 1.0, DOWN = -1.0;
  
  if (1 < x) {
    return 1/x;
  }
  
  if (0 < x && x < 1) {
    return -1/x;
  }
  
  if (x < -1) {
    return 1/x;
  }
  
  if (-1 < x && x < 0) {
    return -1/x;
  }
  
  if (x == 1) {
    flag = DOWN;
    return 0.0;
  }
  
  if (x == -1) {
    flag = UP;
    return 0.0;
  }
  
  /* x == 0.0 */
  return flag;
}

共役の役割をするものを実数内で考えて、何とかできました。多分大丈夫だと思うんですが…。
共役もどきを 1/x にしましたが、1/(x^3) でも 1/(x^5) でもいいはずです。
しかし、static 変数を使ってしまいました。static 変数を無くすのってできるのかな?感じとしてはできなさそうなんだけど、f(0) が確定しないというのはかなり気持ち悪い。
リンク先のコメントで、選択公理で存在の証明はできたそうなので、任意の実数でf(x)が確定するようなものがあるはずなんだけど挫折。
特別扱いしてるのは、±1、0 だから、±∞ が使えるなら、f(1)=∞、f(∞)=-1、f(-1)=-∞、f(-∞)=1、f(0)=0 とでも定義すればよいからぴったりなんだけど、3 個だとこじつける方法がわからないなぁ。

追記
低レベルなのを書いてみた。

double f(double x) {
  union
  {
    double x;
    struct
    {
      unsigned int u:32;
      unsigned int d:32;
    } b;
  } tmp;
  
  tmp.x = x;
  tmp.b.d += (1<<30);
  return tmp.x;
  
}

エンディアンを別にして、これでもいいと思うんだけどなあ。f の値が NaN になる時の挙動がおかしい。