JAVAを現在勉強中なのですが。
ビット演算子のところで悩んでいます。

「~」のビットごとの補数とはいったいどういうものでどういった時に使うのか、
「>>」と「>>>」のシフトの違いがなんなのかよくわかりません。
簡単でいいので教えていただければ嬉しいです。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

補数を使う場面は幾つかあるのですが、例えば、あるビットだけを OFF したい


(ビットのリセット)ときに使います。

mask = 8;
data = data & ~mask;

とやると、4ビット目だけ OFF になり、他のビットは元の状態のままです。

>> と >>> の違いは、符号ビットの扱いです。一番左のビットは符号ビット
といって、その数値が正か負かを表します。

>>> は、単純にビットをずらすので、一番左のビットは、必ず OFF になります。
>> は、正負の情報を保ちつつビットをずらすので、もし、シフト前に ON で
あれば、シフト後にも一番左のビットは ON のままです。
    • good
    • 0
この回答へのお礼

a-kuma様ありがとうございました。
ビット演算子について、少し理解できたように思えます。

お礼日時:2001/09/11 09:57

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qビットシフト演算子について

-8を2進数で表すと111111111・・・000となるのはなぜですか?

Aベストアンサー

簡単のために8ビットでやってみます。

8は2進数だと
00001000
ですよね。
8 + (-8) = 0 なので、
00001000 + (?) = 00000000 になる?の部分が-8に
なるわけです。

で、2進数で表した8である
00001000のビットを反転させると
11110111ですね。これらを足すと
00001000 + 11110111 = 11111111
になります。この両辺に00000001を足すと
00001000 + (11110111 + 00000001) = (11111111 + 00000001)
00001000 + 11111000 = 100000000
となります。8ビットで表現しているので、
右辺の100000000の先頭1ビットは無視されて、
00000000すなわち0になります。要するに、
00001000(10進の8) + 11111000(10進の-8) = 00000000(10進の0)
というわけで、11111000が-8という事になります。

これの求め方は2進数で表した8のビットを反転させて1を足せば良い事になります。
00001000(10進の8)
反転させて
11110111
1足して
11111000
これが-8となります。

簡単のために8ビットでやってみます。

8は2進数だと
00001000
ですよね。
8 + (-8) = 0 なので、
00001000 + (?) = 00000000 になる?の部分が-8に
なるわけです。

で、2進数で表した8である
00001000のビットを反転させると
11110111ですね。これらを足すと
00001000 + 11110111 = 11111111
になります。この両辺に00000001を足すと
00001000 + (11110111 + 00000001) = (11111111 + 00000001)
00001000 + 11111000 = 100000000
となります。8ビットで表現しているので、
右辺の100000000の先...続きを読む

Qjava >>>記号について

現在Androidアプリを学習しています。

以下コードの解釈がわかりません。

呼び出し
int idx = rand(6);

private static Rondom rand = new Rondom();
public static int rand(int num) {
return (rand.nextInt() >>> 1) % num;
}

特に >>> の記号が意味不明です。
ご教授のほどよろしくお願い致します。

Aベストアンサー

> 上記コードの場合、乱数をビットシフトして6で割ったあまりと、回りくどいやり方が必要なのでしょう

まず、numで割った余り、というのは、 0<=n<numの整数乱数nを求めるため、というのはよろしいでしょうか。

ビット演算ですが、今回の例では、乱数の質を高めようとしているのだと思われます。

コンピュータが発生する乱数の多くは「疑似乱数」といって、一見バラバラに見えて、実際には計算によって求めたもので、同じ初期条件からは同じ「乱数」が同じ順番で発生します。

JavaのRandomには「線形合同法」という非常に単純で、質のあまりよろしくないものが使われています。
ここでいう質とは、値が偏らない、とか、短いパターンを繰り返さない(奇数のあとには必ず偶数、とかいうことが無い)とかいうものです。

線形合同法では、上位ビットや下位ビットに傾向が出やすいので、真ん中あたりを使って質を上げる、というテクニックがあります。劇的な効果は無いですが、ちょっとだけましになります。

参考URL:http://www001.upp.so-net.ne.jp/isaku/rand.html

> 上記コードの場合、乱数をビットシフトして6で割ったあまりと、回りくどいやり方が必要なのでしょう

まず、numで割った余り、というのは、 0<=n<numの整数乱数nを求めるため、というのはよろしいでしょうか。

ビット演算ですが、今回の例では、乱数の質を高めようとしているのだと思われます。

コンピュータが発生する乱数の多くは「疑似乱数」といって、一見バラバラに見えて、実際には計算によって求めたもので、同じ初期条件からは同じ「乱数」が同じ順番で発生します。

JavaのRandomには「線形合同法」...続きを読む

Qシフト演算子について・・・意味がわかりません(T_T)

左シフト演算子<<は最上位ビットの上位を削除して最下位に0を追加、
右シフト演算子>>は最下位ビットが削除されて、最上位ビットに最上位ビットと同じ値が補充される、
論理右シフト>>>は最下位ビット削除され、最上位に0が補充される。

と、ここまではわかりました・・・

ある問題で

int n = -1>> 31;

でnはいくつになるか?というのがあったんですが、
解説の意味がわかりません。
回答はー1です。
「>>演算子によるシフトでは符号ビットが拡張される」
意味がわかりません・・・(@_@)
「>>>演算子であったなら、符号ビットがゼロになるのでN=1となる」
え・・・???!!!
ふごーびっと???

シフト演算子ですから、
「-1の31こ右にビットをシフトする」
んだな・・・と思ったところ、
まったくどう考えてよいのかわからず、
回答を見たところ、余計わからなくなりました。

だれかたすけてください(T_T)

Aベストアンサー

右シフトの動作はこちらの通りです。
http://www.microsoft.com/japan/msdn/library/ja/jscript7/html/jsoprrshift.asp

右に1ビットシフトしたとき、全体のビットが右に1ビットシフトし、
最上位ビットには符号ビットが入ります。
-1は、全ビットが1で、符号ビット(MSB=最上位ビット)も1ですから、
何ビット右シフトしても常に-1です。

参考URL:http://www.microsoft.com/japan/msdn/library/ja/jscript7/html/jsoprrshift.asp

Qjavascriptでビット演算子の「^」を理解する方法を知りたいです。

例えば、こんなものを作ってみましたが、いまいちピンと来なくて。。
どの様な法則の上で動いているのかがわからないです。
そして、何の為に使っているのががわからないです。
javascriptでビット演算を使用するメリットはあるのでしょうか?
(処理が早くなる、というのはwikiにも説明があるのでわかりましたが。)
何とぞ、よろしくお願い致します。

x = new Array(
1^0,
1^1,
1^2,
1^3,
1^4,
1^5,
1^6,
1^7,
1^8,
1^9,
1^10,
1^11,
1^12,
1^13,
1^14,
1^15,
1^16,
1^17,
1^18,
1^19,
1^20
);

for (i=0; i<=20; i++){
document.write(
i + ":" + x[i] + "<br>"
);
}

Aベストアンサー

質問者様がまだ見ていらっしゃるかどうかは不明ですが…。
xorの処理をここで纏めてみます。
0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

比較したものが同じ値の時、0(false)になり、
比較したものが違う値の時、1(true)となります。

さて、では質問者様の例を考えてみます。
まずは 1^0
これを2進数で考えると以下のようになります。
0001 = 1
0000 = 0
このように縦にして、同じビット同士でxorを行います。
結果は
0001 = 1
0000 = 0
--------
0001 = 1
となります。
こうした方が分かりやすいですかね…。
0xor0=0
0xor0=0
0xor0=0
1xor0=1
↓  ↓  ↓
1  0  1

次に 1^1 で考えてみます。
0001 = 1
0001 = 1
--------
0000 = 0
となります。
ご提示いただいたものをいくつか2進数に直して計算結果を書いてみます。

0001^0000 (=0001) = 1(1^0の結果)
0001^0001 (=0000) = 0(1^1の結果)
0001^0010 (=0011) = 3(1^2の結果)
0001^0011 (=0010) = 2(1^3の結果)
0001^0100 (=0101) = 5(1^4の結果)
0001^0101 (=0100) = 4(1^5の結果)
0001^0110 (=0111) = 7(1^6の結果)
0001^0111 (=0110) = 6(1^7の結果)
0001^1000 (=1001) = 9(1^8の結果)
0001^1001 (=1000) = 8(1^9の結果)
0001^1010 (=1011) = 11(1^10の結果)
0001^1011 (=1010) = 10(1^11の結果)
0001^1100 (=1101) = 13(1^12の結果)
0001^1101 (=1100) = 12(1^13の結果)


0001^1111 (=1110) = 14(1^15の結果)
00001^10000 (=10001) = 17(1^16の結果)

1^16ですが4桁では表示しきれない値になったので繰り上げしました。
この時、混乱しないように最初のうちは上記のように桁合わせして計算した方が良いと思います。


>mizutaki様
スイマセン、気になったのでつっこませて下さい。
>>XORはビット演算の結果を反転させ
違うと思います。
ビットの反転はNOT(~)だと思います。

質問者様がまだ見ていらっしゃるかどうかは不明ですが…。
xorの処理をここで纏めてみます。
0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

比較したものが同じ値の時、0(false)になり、
比較したものが違う値の時、1(true)となります。

さて、では質問者様の例を考えてみます。
まずは 1^0
これを2進数で考えると以下のようになります。
0001 = 1
0000 = 0
このように縦にして、同じビット同士でxorを行います。
結果は
0001 = 1
0000 = 0
--------
0001 = 1
となり...続きを読む

Qビット演算子が使えない。

こんにちは現在Javaをやっているいのですが、

//計算を行うプログラムです。
public class keisan{

public static void main(String args[]){

int num1=10;
int num2=15;

System.out.println("num1とnum2にいろんな演算を行っています。");
System.out.println("num1+num2は"+(num1 | num2)+"です。");
}

}

コンパイルはできましたが、
Exception in thread "main" java.lang.NoClassDefFoundError: keisan[

とエラーがでてきます。どうしたら良いのでしょうか?
お願いします。

Aベストアンサー

実行するとき
java keisan.java
と入力していませんか?

java keisan

と入力して実行してみてください


このカテゴリの人気Q&Aランキング

おすすめ情報