2進数の掛け算
2進数をシフト操作することによって、ある2進数の2の累乗倍の値を求めることができるようになりました。
しかし、それでもまだ、ある2進数を3倍、7倍した時などの2の累乗倍以外の値を求める場合には対応できません。
このような場合には、ある2進数に掛ける値をシフト操作の表現に置き換えることによって対応することが出来ます。
たとえば、「$10101$」という2進数を$11$倍した値を求めたいとします。
この時、2進数と10進数という違いはありますが、
10101\times11
という式になりそうです。
ここで、「$11$」という掛ける数(乗数)に着目します。
「$11$」を2の累乗の形で表現すると、以下の数式から、$2^3+2^1+2^0$と表すことが出来ます。
\begin{align}
11&=8+2+1\\
&=2^3+2^1+2^0
\end{align}
これを用いて、先ほどの掛け算を置き換えてみます。
\begin{align}
10101\times11&=
10101\times(2^3+2^1+2^0)\\
&=(10101\times2^3)+(10101\times2^1)+(10101\times2^0)
\end{align}
分配法則から、2進数を2の累乗の数にそれぞれ掛け合わせ、その後足し合わせるという形になりました。
ここで、少しシフト演算の仕組みを振り返ってみましょう。
2進数をシフト演算する場合、左にn桁だけずらした時(桁をn桁増やした時)に$2^n$倍され、
右にn桁だけずらした時(桁をn桁減らした時)に$2^{-n}$倍されます。
このことから、2進数に2の累乗の数をそれぞれ掛け合わせるというのは、2進数を2の累乗の指数分左にシフトさせるということになります。
したがって、先ほどの数式を言葉で表現するならば、以下のようになります。
\begin{align}
10101\times11&=(10101\times2^3)+(10101\times2^1)+(10101\times2^0)\\
&=(10101を左に3シフト)+(10101を左に1シフト)+(10101)
\end{align}
$2^0$の部分に関しては、「$10101$を左に$0$シフトさせた数」なので元の数のままになります。
この式を計算してみると、以下のようになります。
\begin{align}
10101\times11&=(10101\times2^3)+(10101\times2^1)+(10101\times2^0)\\
&=10101000+101010+10101\\
&= 11100111
\end{align}
$10101$と、この数を11倍させて得られた$11100111$という2つの2進数をそれぞれ10進数に基数変換すると以下のようになります。
2進数 | 10進数(基数変換) | 大きさの変化 |
---|---|---|
10101 | 21 | |
11100111 | 231 | 11倍 |
この表から、2進数$10101$が正しく11倍され、$11100111$になったことが確かめられました。 |
2進数の割り算
今度は2進数の割り算について考えていきたいと思います。
例として、2進数「$11100111$」を10進数で「$21$」にあたる2進数「$10101$」で割り算した時の値を求めたいとします。
この割り算を数式に表してみると次のようになります。
\begin{align}
11100111\div10101
\end{align}
計算に入っていく前に、「割り算」そのものについて考えてみたいと思います。
「割り算」とはある大きさの数を一定の数でいくつに(何回)分割できるかという計算のことを意味します。
言い換えると、「割り算」はある大きさの数から一定の数を何回引き算できるかを求める計算ということになります。
したがって、この例で考えるならば、「$11100111$」という2進数を「$10101$」で何回引き算することができるかを求める計算をするわけです。
それでは、実際に計算を行なっていきます。
2進数「$11100111$」を「$10101$」で割り算する方針としては、10進数における割り算と基本的には同じです。
つまり、「$11100111$」を超えない大きさの、「$10101$」をX倍した数を用意して、「$11100111$」から引き算をします。そして、引き算の結果を同じように「$10101$」をY倍した数で引き算していくというものになります。
ただし、この過程の『「$10101$」をX(Y)倍した数を用意』する部分に関しては、「$10101$」を左シフト演算することによって作るという注意点があります。
まず、「$11100111$」を超えない数を「$10101$」の左シフト演算によって用意します。
桁数 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
---|---|---|---|---|---|---|---|---|
割られる数 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
割る数 | 1 | 0 | 1 | 0 | 1 |
「$11100111$」は8桁で「$10101$」は5桁なので、桁数を合わせるために「$10101$」を左に3ビットシフトさせます。
左シフト演算により、「$10101$」は$2^3$倍されて「$10101000$」という数になりました。
桁数 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
---|---|---|---|---|---|---|---|---|
割られる数 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
用意した数 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
ここで、一度「割られる数」から「用意した数」を引き算します。
11100111-10101000=00111111
すると、「$00111111$」という数になりました。
それではさらに、この数を超えない数を「$10101$」の左シフト演算によって用意します。
桁数 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
---|---|---|---|---|---|---|---|---|
割られる数 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
用意した数 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
「$10101$」を左に1ビットシフトさせて「$101010$」という数になりました。
左シフト演算により、「$10101$」は$2^1$倍されています。
ここで、やはりまた引き算を行います。
00111111-00101010=00010101
すると、「$00010101$」という数になりました。
「$00010101$」は「割る数」の「$10101$」と等しいため、左シフト操作は不要です。
だから、ここでは「$10101$」を$2^0倍$した数を用意したということになります。
00010101-10101=0
引き算の結果、「$0$」となったため、割り算はここで終了となります。
ここで、「$11100111$」は「$10101$」によって何回引き算できる数かを求めます。
言い換えると、「$11100111$」は「$10101$」を何倍した数かを求めれば良いことになります。
これまでの計算から、「$11100111$」は「$10101$」を($2^3+2^1+2^0$)倍、つまり$11$倍した数であるということが分かります。
したがって、「$11100111$」は「$10101$」を$11$回引くことができる数であり、
$11100111\div10101=1011(10進数で11)$となります。
参考にさせて頂いた書籍
きたみりゅうじ 『キタミ式イラストIT塾 基本情報技術者平成31/01年』 技術評論社 2019年
学習してみて
今回で基本的な2進数の四則演算を学習し終えることが出来ました。
2進数の計算方法はなかなか特徴的でしたが、シフト演算などの仕組みを把握していれば理解しやすくなるかと思います。
今回までは主に整数の計算でしたが、次回からは小数点の表現方法について学習していきます。