2019-06-30

Cにおける偶数奇数判定

偶数奇数を判定するための途方もないプログラミングコード話題

http://blog.livedoor.jp/itsoku/archives/55507489.html

x and 1 (ビット演算)でいいじゃんと言う話

偶数奇数判定は、通常、剰余を使って、

x mod 2

で行いますが、ビット演算を使い、最下位ビットが立ってるかチェックする

x and 1

でいいじゃんという話がコメント欄でちらほら出てきます

負の表現に2の補数を使うプログラミング言語では問題無いのですが、Cではちょっと問題が起きます

プログラミング言語Cかつ符号付き整数とき問題

X3010:2003 プログラミング言語 C 6.2.6.2 整数

符号付き整数型において、オブジェクト表現ビットは、値ビット、詰め物ビット、および符号ビットの三つのグループにわけられなければならない。

詰め物ビット存在しなくてもよく、符号ビットは丁度一つでなければならない。それぞれの値ビットは、対応する符号なし整数型のオブジェクト表現における同じビットと同じ値をもたなければならない。(略)

符号ビットが0であれば、それは結果の値に影響を及ぼしてはならない。符号ビットが1であれば、値は次に示す方法の一つにしたがって変更されなければならない。

- 符号ビットが0のときの値を負数化した値[符号絶対値(sign and magnitude)]

- 符号ビットが値-(2N)をもつとするときの値[2の補数(two's complement)]

- 符号ビットが値-(2N-1)をもつとするときの値[1の補数(one's complement)]

これらのうちいずれが適用されるかは処理系定義とする。

負の表現に1の補数が使われている処理系問題が起きます

たとえば、符号付き整数8ビットで(-1)を表現すると、

2の補数の場合(1111 1111)2

1の補数の場合(1111 1110)2

と、表現が異なります

よって、処理系が2の補数を採用している場合では問題ありませんが、1の補数を採用している場合に判定が逆になります

1の補数を採用してる処理系なんてあるの(プンスコ)

UNISYS社のClearPath Dorado Systems(ClearPath OS2200)で採用されているという話です。

参考

INT16-C. 符号付き整数表現形式について勝手な想定をしない

https://www.jpcert.or.jp/sc-rules/c-int16-c.html

  • だからCの移植性なんて、あってないものだよね。 移植性が欲しいならJavaとか.NETを使うべきだろうね。

    • でもCの移植するのなんか組み込みとかドライバとかの案件ばかりでC#もJavaも使えんやろ

      • 確かにそうだね。 ドライバ開発ってこんな細かい知識がないといけないなんて大変だな・・・。 僕の仕事は高レベルの開発でいいや。

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん