クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

負の数と小数をビットで表す(2の補数)

このレッスンのあとで: 負の数と小数をビットで表すことができる。

50分のレッスンコマンド7件コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

110円にならない税込み価格

冬の札幌の気温は -8℃ になることがあります。コンビニの100円のおにぎりは、税込みで100 × 1.1 円です。

前回、1バイトは0から255を表しました。マイナスの記号も小数点もありませんでした。では、コンピュータは0より小さい数や小数をどう記録するのでしょうか。

このレッスンのゴール

メモ

負の数と小数をビットで表すことができる。

キーワード

ことばいみ
2の補数負の整数をビットで表す、ふつうのやり方
最上位ビットいちばん左の、重みがいちばん大きいビット
オーバーフロー答えが大きすぎて、決まったビット数に入らないこと
固定小数点小数点の位置がいつも同じ場所にある数
浮動小数点数字と、小数点を動かす指数を分けて記録する数
丸め誤差値をぴったり記録できないために出る小さなずれ

学生が入力するセルは、このプレビューでは空白です。

始める前に

メモ

上のバーの Start the lab を押し、マシンが動き出すまで待ってください。Run ボタンは、順番にコマンドをマシンのターミナルに入力します。

いちばん上のビットはマイナス

2の補数では、1バイトのいちばん左のビットの重みを 128 ではなく -128 にします。残りの7ビットは、ふつうの重みのままです。

だから、0で始まるバイトは0か正の数です。1で始まるバイトは負の数です。1バイトで表せるのは -128 から 127 になります。数の種類は、前と同じ256個です。

例: 同じ1バイトの2つの読み方

ビット0から255として読む2の補数として読む計算
00000101554 + 1
0111111112712764 + 32 + 16 + 8 + 4 + 2 + 1
10000000128-128-128
11111100252-4-128 + 64 + 32 + 16 + 8 + 4
11111111255-1-128 + 127

学生が入力するセルは、このプレビューでは空白です。

ビットを反転して1を足す

負の数を早く書く方法があります。まず、正の数を8ビットで書きます。次に、すべてのビットを反転します。0は1に、1は0にします。最後に1を足します。

同じ手順で、負の数を正の数にもどすこともできます。

例: -4 を書く

手順ビット
4を書く00000100
すべて反転する11111011
1を足す11111100

学生が入力するセルは、このプレビューでは空白です。

arch フォルダへ移る

コマンド
cd ~/arch

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

-4 を返す C プログラムを書く

コマンド
printf 'int main(void) { return -4; }\n' > minus.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コンパイルする

コマンド
gcc minus.c -o minus

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

実行する

コマンド
./minus

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

返した値をシェルに聞く

コマンド
echo $?

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

ビットそのものが「負の数」だと言っている、と考える人がよくいます。そうではありません。プログラムは -4 を 11111100 として返しました。シェルはこれを0から255として読むので、252 と表示しました。同じビットが、読み方しだいで -4 にも 252 にもなります。

固定小数点は小数点を動かさない

税率の計算は、小数で書くとまちがえやすいです。そこで多くのプログラムは、100 × 110 ÷ 100 のように整数だけで計算します。整数の計算は正確です。

2進数でも、小数点の場所を決めておけます。小数点の右のけたの重みは、2分の1、4分の1、8分の1と半分になります。

例: 5.75 を固定小数点で表す

けたの重み8421.1/21/41/81/16
ビット0101.1100
足す値0401.1/21/400

学生が入力するセルは、このプレビューでは空白です。

浮動小数点は小数点を動かす

固定小数点では、とても大きい数ととても小さい数を同じビットに入れられません。浮動小数点は、数字と指数を分けて記録します。5.75 を 0.575 × 10 と書くようなものです。

0.1 や 1.1 のような多くの小数は、2進数ではぴったり書けません。とても近い値として記録されます。

100に1.1をかける

コマンド
python3 -c "print(100 * 1.1)"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

1.1の本当の中身を見る

コマンド
python3 -c "print(format(1.1, '.20f'))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

さらに挑戦: 16ビットの得点

あるゲームは、プレイヤーの得点を16ビットの2の補数で記録しています。記録できるいちばん大きい得点と、いちばん小さい得点はいくつですか。

1バイトと同じく、いちばん上のビットの重みはマイナスです。いちばん大きい得点にさらに1点入ると、どうなるかも考えてください。

このラボとソースについて: コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。