• 受付
  • 困ってます

1バイトの数字の範囲

  • 質問No.9685984
  • 閲覧数77
  • ありがとう数4
  • 気になる数0
  • 回答数9

お礼率 51% (381/746)

8桁の2進数(1バイト)であらわす数字の範囲は-128~127ということです。
その説明として、111111111が最小で、01111111が最大であり、左端のビットが正負を表すので絶対値として意味のあるのは残りの7bitの1111111すなわち127とのことです。そしたら、-127から127のはずです。さらに1を引く(絶対値に1を足し負の数とする)と10000000となりこれが最小を意味し、2^8=128で左端が1なので負になる、と言う風に読める説明があります。
この説明が腑に落ちないのですが。問題は左端の8bit目が数値1とみたり、正負とみたりしているようです。あるいは同時にどっちもの意味になっているようです。このような説明でもいいのでしょうか。説明というよりそういう取り決めということになるのでしょうか。

回答 (全9件)

  • 回答No.9

ベストアンサー率 48% (4477/9286)

> ”2の補数表現”によって負数を表すということですが、正の数はどうなるのでしょうか。数はすべて”2の補数表現”になるのでしょうか。

正の数には、補数表現という考え方はありません。
8bitだと符号なしと考えると、0~255の数なわけで、この256個の数をゼロと正の数と負の数にうまく分割する方法を考えるわけです。ゼロはいいとして、あと最上位bitが0の時を正の数とすると、1~127については、符号ありの時と符号なしの時で同じビット表現になるので、これを採用します。
従って、最上位bitが1の時が負の数を表すことにします。

方法1:
残り7bitで絶対値を表す。これが絶対値表現です。
-1 は 1000 0001 ですね。
この方法だと、0000 0000 も 1000 0000 もゼロです。
例えば、3 + (-1) = 2 を考えると、
0000 0011 + 1000 0001 を符号なし整数のつもりで加算すると、1000 0100 になります。これは -4 です。ということは、符号あり加算は符号なし加算で代用できず、別の加算回路を作らないといけないことがわかります。

方法2:
256から絶対値を引いた数のビットバターンを負の数の表現とする。これが2の補数表現です。
つまり、N + (-N) = 256 になるように -N のビットパターンを決めます。
N=1とすると、-N は255のビットパターン、つまり 1111 1111 が-1です。
256は8bitで表せませんが、下位8bitはオール0です。
つまり、8bit目から9bit目への桁上がりを無視して加算すると、N + (-N) = 0 ということになり、符号あり数の加算と、符号なし数の加算が同じ命令で実行できることになります。
例えば、3 + (-1) = 2 を考えると、
0000 0011 + 1111 1111 を符号なし整数のつもりで加算すると、1 0000 0010 になります。下位8bitを見ると、2が得られます。

方法3:
N + (-N) = 255 となるように、-N のビットパターンを決めます。
これが1の補数表現です。(すいません。No4の回答では間違えて書いてしまいました)
-1 は 1111 1110 になります。

例えば、3 + (-1) = 2 を考えると、
0000 0011 + 1111 1110 を符号なし整数のつもりで加算すると、1 0000 0001 になります。下位8bitを見ると、1が得られます。ということは、符号あり加算は符号なし加算で代用できず、別の加算回路を作らないといけないことがわかります。
  • 回答No.8

ベストアンサー率 13% (260/1908)

No.3です
> -1が11111111であり、0が00000000となると、10進数での-1+1=0 となる演算は2進数ではどうなるのでしょうか。11111111+1=00000000 になるのでしょうか。負の数⇒正の数(その逆も)がスムーズに行かないように見えるのですが。

11111111+00000001=100000000となり、9バイト目に桁あふれが起きます。これを1バイトだけで表現するなら、00000000となります。正の数の最小値である0に加算していくと正の数最大値の127になります。ここに1加算すると負の数の最小値-128になります。実際の数ではなく8ビットの制約のあるなかでは、シームレスです。
  • 回答No.7

ベストアンサー率 72% (4432/6139)

他カテゴリのカテゴリマスター
人間の側が、1バイトのデータを見るとき、
符号なしとして見るとき: 0000 0000~1111 1111 を 十進数0~255として扱う
符号ありとして見るとき: 0000 0000~0111 1111 を0~127、1000 0000~1111 1111を -128~-1 として扱う
ということにしているわけですが、根拠なしにしているわけではありません。

「コンピュータ上で素直に演算できる」からです。

ちょっとだけ2進数の表を書いておきます。
(2進数8bit) / (十進数)
0000 0101 / 5
0000 0100 / 4
0000 0011 / 3
0000 0010 / 2
0000 0001 / 1
0000 0000 / 0
1111 1111 / -1 ※符号なし255
1111 1110 / -2 ※符号なし254
1111 1101 / -3 ※符号なし253
1111 1100 / -4 ※符号なし252

この表の中で、いくつかの演算をしてみましょう。

例えば、2 + 3 を2進数で表すと 0000 0010 + 0000 0011 となりますね。
足して2になる桁は、次の桁へ繰り上がります。
 0000 0010 ←十進数2
+)0000 0011 ←十進数3
---------------------
 0000 0101 →十進数5
当然ですが、5という結果が出ます。

今度は、2 - 4 という演算をしてみましょう。
これはすなわち、2 + (-4) です。
2進数で表すと、0000 0010 + 1111 1100 。加算ですから、それぞれの桁を足します。
 0000 0010 ←十進数2
+)1111 1100 ←十進数-4
---------------------
 1111 1110 →十進数-2

はい、同じ加算演算で正しく計算できました。
ちなみにこのビット列を符号なしとしてみると、こうなります。
 0000 0010 ←十進数2
+)1111 1100 ←十進数252
---------------------
 1111 1110 →十進数254

2 + 252 = 254 として、やはり正しい演算となっています。

つまりコンピュータ自体は、左端ビットが符号であるかどうかなんて考えておらず、愚直にビット演算を行っているだけなんです。
※機械語命令の一部には、左端ビットを符号ビットとして扱う命令もあるのですが

さてそういうわけで、

>符号ありとして見るとき: 0000 0000~0111 1111 を0~127、1000 0000~1111 1111を -128~-1 として扱う

こう見たときに、ちょうど左端ビットの0/1が+/-と一致しているので、「そのデータを符号ありとして見る」時には「左端ビットを符号ビットとして見てよい」ことになるんですね。

ただし、2進数 0000 0001 のマイナス値というのは、符号ビットだけ1にした 1000 0001 ではありません。
全ビット反転させた1111 1110 でもありません。
十進数-1の2進数は、1111 1111です。
この辺が、ちょっと人間の感覚とずれるところなのかな、と思います。
  • 回答No.6

ベストアンサー率 34% (142/408)

質問者様が疑問に思われているのは、1の補数で表した場合ではないでしょうか。
1の補数は、8ビット目を符号ビットとして表し、正の数字なら0~127、負の数字なら-0~-127が表現できます。しかし、0と-0は同じ数字であるため、実用向きではありません。そこで2の補数が採用されており、正の数字は0~127、負の数字は-1~-128として表している訳です。
2の補数のビット表現については、他の回答にもあるため割愛します。
  • 回答No.5

ベストアンサー率 28% (1364/4849)

2の補数表現の場合、左端の8ビット目は正負の判断に使えはしますが正負を表す符号ビットというわけではありません。
  • 回答No.4

ベストアンサー率 48% (4477/9286)

> 問題は左端の8bit目が数値1とみたり、正負とみたりしているようです。

符号付8bit数値の場合、左端のビットは符号の意味だけです。数値1とみることは無いです。

> その説明として、111111111が最小で、01111111が最大であり、

これは、「1000000が最小で、01111111が最大であり、」のコピペミスでしょうか?ミスでない場合、それは「1の補数表現」という世の中ではまず使われていない負数表現についての説明です。
世の中で一般的に使われている負数表現は「2の補数表現」で、その場合は、「1000000が最小で、01111111が最大であり、」です。
お礼コメント
skmsk1941093

お礼率 51% (381/746)

回答ありがとうございます。私は以下のように間違って考えていました。”左端8bit目は符号、残りの7bitは数値であり、そのため最小の数は7bitがあらわす最大の数1111111=2^7+2^6+2^5...1=127に対してその左端を1にして負にした-127である”ということです。しかしそれは間違いでさらに1を引き-128となるということです。
この辺の理解ができていないのです。”2の補数表現”によって負数を表すということですが、正の数はどうなるのでしょうか。数はすべて”2の補数表現”になるのでしょうか。
投稿日時:2019/12/04 08:04
  • 回答No.3

ベストアンサー率 13% (260/1908)

最小は11111111ではなく10000000です。
11111111は10進数で-1です。
符号付きの場合、先頭ビットは正負を表しますが、残りの7ビットは0000000が最小値で1111111が最大値です。つまり負の数は10000000~11111111で-128~-1を表し、正の数は00000000~01111111で0~127を表します。

色々と勘違いがありそうなので、もう一度勉強し直したほうが良いと思います。
お礼コメント
skmsk1941093

お礼率 51% (381/746)

回答ありがとうございます。理解していないことを放置していました。この道が専門ではないもので。ご説明だと負の数と正の数での体系が違うと言う風に見えてしまいます。
-1が11111111であり、0が00000000となると、10進数での-1+1=0 となる演算は2進数ではどうなるのでしょうか。11111111+1=00000000 になるのでしょうか。負の数⇒正の数(その逆も)がスムーズに行かないように見えるのですが。
投稿日時:2019/12/04 08:15
  • 回答No.2

ベストアンサー率 17% (201/1169)

説明がごちゃごちゃですね。
1)2の補数
2進数の8桁は0から255を表せます。
じゃぁ、マイナスはどうするの?ということで
111110111
+00001000(10進数の8)
-------------
1000000000 ->桁落ちして=0 つまり8を足して0になるわけだから
上の数字を-8とすることでマイナスを表記します。

なので取り決め(定義)として
11111111 を-1
11111110 を-2


10000000 を-128とします。
10000000(10進数の128) を足せば
-------------
100000000 桁落ちして0になりますから-128です。

もちろん
00000000 が0
00000001 が1
00000010 が2

01111111  が127を表します。

2)1の補数
左端を符号ビットとしてあとの7桁で数字を示すものです。
なので-127から127までしかありません。
お礼コメント
skmsk1941093

お礼率 51% (381/746)

回答ありがとうございます。以下のご説明が分からなかったのですが。
111110111
+00001000(10進数の8)
-------------
1000000000 ->桁落ちして=0

各ビットの桁のところを足せばいいのだから、111111111になるのかなあと思ったのですが。
取り決め(定義)としたら、それはそうしなければならないことはないけれどそうした、ということであり、理由が必ずしも必要ないということになるでしょうか。
投稿日時:2019/12/04 08:31
  • 回答No.1

ベストアンサー率 26% (617/2365)

>>この説明が腑に落ちないのですが。問題は左端の8bit目が数値1とみたり、正負とみたりしているようです。あるいは同時にどっちもの意味になっているようです。このような説明でもいいのでしょうか。

いいです。
i符号なし型と符合有り型があります。

>>-127から127のはずです。
これはおかしいでしょ。2^8=256.。つまり表現できる数字は256。
-127の絶対値は127、127+127で254。ゼロも有るから+1で255。1つ足りなくなってしまう。

なにで使いたいのでしょう。
普通の仕事だとビットまで落とさずに、16新にするのがおおいかなと思います。
例えばJISの1は31'HEX。ビットに直すと00110001
お礼コメント
skmsk1941093

お礼率 51% (381/746)

回答ありがとうございます。この質問のもともとの主旨は、なぜそうなっているのかではあったのですが、気が変わってきて、どういう風に理解したらいいかになりました。理由は問わないけど、考え方を覚えたいということで、フレミングの右手(左手?)の法則と同じです。”そう言う風に覚えましょう”ということです(それが少ないほどいい)。そこで以下のことを考えました。
” nビットの2進数で正負の整数を表現する場合、最小の数(負)はnビット目(左端)が1であり、それ以外が0、最大の負の整数(当然,-1)はすべてのビットが1である。”
これを出発点に考えればいい。例えば-1は11111111ですが、これに1を足すと100000000となり、左端の1は9ビット目となって存在しない。したがって0000000となり0となっている。、ということなのですが。
投稿日時:2019/12/04 12:18
関連するQ&A

その他の関連するQ&Aをキーワードで探す

ピックアップ

ページ先頭へ