SUFARYでは、 とてつもなく巨大な配列を二分探索する必要があるのだが、 これまでオーバーフローについては何も考慮していなかった。 二分探索の部分を簡略化するとこんな感じである。
while (left <= right) { /* left も right も INT 型 */ INT middle = (left + right) / 2; if (x[middle] < target) left = middle + 1; else if (x[middle] == target) return middle; else right = middle - 1; }2行目で領域の中心を計算するとき left + right がオーバーフローする可能性が かなりあるのだ。 以下のように単純に unsigned にキャストすれば済みそうなものだが、 この場合、INT は signed とは限らないのでダメである。
middle = ((unsigned INT)left + (unsigned INT)right) / 2;そこで、ちょっと処理は複雑になるが以下のようにしてみた。
if ((left & 1) == 1 && (right & 1) == 1) middle = left / 2 + right / 2 + 1; else middle = left / 2 + right / 2;一般にはこういうときどのようなコードを書くのだろうか。 一昔前のビット数の少ないコンピュータでは頻出した問題だと思うのだが、 関連文書か何かどなたかご存知ありませんか? また、「もっと良い方法がある」という方、ぜひ教えて頂けないでしょうか。