- - PR -
奇数、偶数の判断の方法
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-12-05 11:43
i & 1 はビット演算をしています。
たとえば、3 は2進数で表すと 0011 、4 は同じく 0100 となります。 これと 0001 を AND 演算するので、 0011 AND 0001 -------- 0001 0100 AND 0001 -------- 0000 となります。 #2進数や論理演算がよくわからなかったら、なんか参考書をあたってください。 つまり 0001 と AND 演算した結果が 0001 であれば(最下位ビットが立っていれば)奇数であると判断できるのです。ちょっとコンピュータ寄りの考え方で一見わかりにくいのですが、2で割って余りを比較するよりは早く処理できます。 もっとも、javac なり JVM の最適化具合によっては結局同じ処理をしてくれる可能性もありますし、実際の処理速度の差は微々たるものなので自己満足に近いものもあります。 アセンブリ言語や C 言語では結構普通にこういうプログラムをします。 うろ覚えですが、例えば Z80 では LD A 3 //A レジスタに 3 を代入 RLCA //A レジスタを右にシフト 最下位ビットはキャリーフラグへ JR NC odd //キャリーフラグが立っていなければラベル odd: へ //奇数の処理 odd: //偶数の処理 というように書きます。全然意味わかりませんよね?Java では処理速度の向上は Javac/JITコンパイラにまかせて、人間はメンテナンス性の良さを重視する傾向にあるので、素直に i % 2 == 0 と書くか、このような凝った書き方する場合はしっかりコメントを書いた方が良いですね。 [ メッセージ編集済み 編集者: インギ 編集日時 2003-12-05 11:54 ] | ||||||||
|
投稿日時: 2003-12-05 14:43
ほむらです。
オフトピですが。。。 -------------- 新人さんにプログラム(の文法)を教えていたときに 論理演算子(&&,||)とビット演算子(&,|)の区別をなかなか理解してもらえずに 説明でかなり悩んだことがあります。 論理演算子は論理式(条件文)を書くときに使って ビット演算子は算術式(計算式)で使うんだよー とかなり砕いた(ある意味いいかげん)いいかたで うなづいてはいましたが、果たして理解していたのか今も謎です。 #ビット演算は時々便利だったりするので覚えておいて損はないですよね。 | ||||||||
|
投稿日時: 2003-12-06 01:04
失礼しました。私の大変勘違いでした。ビット演算の話ですね。 (i & 1)のあとに==0があるのに築かず、すいません。
下記は無視してください。 =================================== ボムさんが聞かれているのはCとJAVAの違いではないでしょうか・・・。(私がスーパー勘違いしていたらすいません) ------------------------- if((i & 1) == 0){ //偶数 }else{ //奇数 } -------------------------- ビット演算をして、ifの括弧のなかが0になれば偽、1であれば真です。 JAVAはtrueかfalseにしないといけないんですよね?(ちょっと自信なく・・・、違っていたら訂正願います)なので、Cの場合であれば(i & 1)とビット演算しているわけです。 ちなみに、Cのコードは下記の感じになります。(ちょっと、ここの掲示板に乗せるのは気が引けますが・・・)コンパイラがあったら試してみてください。(当たり前のことですが、コンソールに表示できるコンパイラで試してくださいね。昔、コンソールに表示できないCのコンパイラを使用していたことがあって、苦労したことがあります。(お恥ずかしい・・・)) #include<stdio.h> main(void){ int i1 = 0; int i2 = 1; if(i1){ printf("i1 : 0"); } if(i2){ printf("i2 : 1"); } } [ メッセージ編集済み 編集者: begood 編集日時 2003-12-06 01:23 ] | ||||||||
|
投稿日時: 2003-12-06 11:49
お世話になっております。
元のスレッドの内容とはずれてしまいますが、
DBのint型のフィールドに、複数のフラグ状態を保存するときに使用していたりします。 DBから取得したときに、目的のフラグが立っているかどうかを、 if ((flag & 0x1) == 0x1) { } else if ((flag & 0x2) == 0x2) { } ・・・のような感じでチェック。 | ||||||||
|
投稿日時: 2003-12-08 09:16
人様のスレッドで質問してしまい、すみませんでした。
こーゆー場合は別にスレッドを立てるべきでした。 皆さんのご説明が非常にわかりやすく、理解できました。 ただ、私に使えるかは微妙ですが・・・ | ||||||||
|
投稿日時: 2003-12-08 14:01
ども、ほむらです。
------- syo氏へ 僕もフラグの管理でビット演算は良く使用していました。(C++) えと、主な使い方としては 1.取得でAND 2.設定でOR 3.トグルスイッチでXOR あとは画像の加工ですか(笑 アルファブレンディングとかぼかしとか。。。ですね 僕の場合フラグそのものは別途定義してましたが。。。 if ((flag & BIT1 ) != 0) { とか 複数の状態を一つの条件でかけるのもビット演算の便利なところですね if ((flag & (BIT1 | BIT2) ) != 0) { ボム氏へ 他の方も言ってらっしゃいますが ビット演算を使用したところでたいした速度の向上は見込めません。 特にJavaの場合バイナリデータの扱いそのものが苦手なようですし。。。 (アプリ特化した言語だけに必要ないのかも?) 最近だと言語によっては、コントロール単位で変数を一つつけて 自動的に関連性をもたせてくれていたりしますしねー なので積極的に利用していく必要性はないと僕も考えますが トレースするときの知識として持っていて損はないかなと。。。>ビット演算(とくにマスク処理) | ||||||||
|
投稿日時: 2003-12-12 11:47
古いスレッドですいません。
一番最初に言われている部分、同じ現象が私のところでもでました・・・。どうしてなのか・・・。負数は2で割ると問題があるのでしょうか? どうしても、負の数で奇数にたどり着けません。absで行えば問題はないと思うのですが、ちょっと考え込んでしまい・・・意見を聞きたく。それとも、このコードが単純な部分で間違っていたら、アドバイス願います。 public void show1(){ Random ran1 = new Random(); int i1 = ran1.nextInt(); int flag1 = i1%2; System.out.println(i1); if(i1>0){ if(flag1 == 0){ System.out.println("正:偶数"); } if(flag1 ==1){ System.out.println("正:奇数"); } } if(i1<=0){ if(flag1 == 1){ System.out.println("負:奇数"); } if(flag1 == 0){ System.out.println("負:偶数"); } } } | ||||||||
|
投稿日時: 2003-12-12 12:02
[ メッセージ編集済み 編集者: ぽん 編集日時 2003-12-12 12:12 ] | ||||||||
