symmetry half
よく、「半分に割るときはビットシフトを使え」という言葉を耳にする。
ところがこのビットシフト、正負に対してシンメトリーになっていない。
シンメトリーになっていないことが、不自然だとは思わない。
むしろ、通常の割り算がシンメトリーになっている事実に、驚愕したことさえある。
(昔の開発環境は、その辺がアシンメトリーだったもので)
unsigned int u;
があるとき、
u = (u / 2);
と
u = (u >> 1);
は同じになる。
ところが、
signed int s;
があるとき、
s = (s / 2);
と
s = (s >> 1);
は同じにならない。
では、どうすれば良いのか。
signed int k = (s >> (sizeof(s)*8-1)); // k = (s>>31);
s = ((s-k) >> 1);
とでもしてやれば良い。
と思って、ふと「ハッカーのたのしみ」を読み返してみたら、普通に同じことが書かれていた。