負の整数を2の補数を使って表現した数を普通に足せば引き算をしたことになります。
演算装置はいままでの正の整数とまったく同じに計算します。それを最高位のビットが1の時だけ2の補数を使って表現していることを考慮して負の整数と解釈するだけです。
ただし、計算結果が表現の範囲を越えると正しい答えになりません。
8ビットでは表現の範囲は -128 以上 127 以下です。
| 内部表現 | 符号つき整数 (十進数) |
|||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| +) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
| 計算値 | 正しい値 | |||||||||
内部表現の薄い青の背景色部分のビットをクリックして数値を設定し、[加算実行]で和を求めます。
もう少し少なめの数で十分なときは4ビットを見てください。
結果の表です。
| コンピュータの 内部表現 |
計算値 | 正しい値 |
|---|---|---|
| 11111110 | -2 | 254 |
| 11111101 | -3 | 253 |
| 11111100 | -4 | 252 |
| 11111011 | -5 | 251 |
| ...... | ||
| 10000010 | -126 | 130 |
| 10000001 | -127 | 129 |
| 10000000 | -128 | 128 |
| 01111111 | 127 | 127 |
| 01111110 | 126 | 126 |
| ...... | ||
| 00001001 | 9 | 9 |
| 00001000 | 8 | 8 |
| 00000111 | 7 | 7 |
| 00000110 | 6 | 6 |
| 00000101 | 5 | 5 |
| 00000100 | 4 | 4 |
| 00000011 | 3 | 3 |
| 00000010 | 2 | 2 |
| 00000001 | 1 | 1 |
| 00000000 | 0 | 0 |
| 11111111 | -1 | -1 |
| 11111110 | -2 | -2 |
| 11111101 | -3 | -3 |
| 11111100 | -4 | -4 |
| 11111011 | -5 | -5 |
| 11111010 | -6 | -6 |
| 11111001 | -7 | -7 |
| 11111000 | -8 | -8 |
| 11110111 | -9 | -9 |
| 11110110 | -10 | -10 |
| ...... | ||
| 10000010 | -126 | -126 |
| 10000001 | -127 | -127 |
| 10000000 | -128 | -128 |
| 01111111 | 127 | -129 |
| 01111110 | 126 | -130 |
| ...... | ||
| 00000110 | 6 | -250 |
| 00000101 | 5 | -251 |
| 00000100 | 4 | -252 |
| 00000011 | 3 | -253 |
| 00000010 | 2 | -254 |
| 00000001 | 1 | -255 |
| 00000000 | 0 | -256 |
詳しい説明は4ビットを見てください。
<script>
var na=0;
var sdna=0;
var nb=0;
var sdnb=0;
var bits = 8;
var ho = 256;//2^8
function flip(e){
var bit = e.firstChild.nodeValue;
if ( bit == 0 ){
bit = 1;
}else{
bit = 0;
}
e.firstChild.nodeValue = bit;
disp();
}
function sdnx(nx,msb){
if (msb==1){
nx -=ho;
}
return nx.toString(10);
}
function disp(){
var tgt = document.getElementById("cala");
var tgttd = tgt.getElementsByTagName("td");
var bstr = "";
for (var i=1;bits>=i;i++){
bstr += tgttd[i].firstChild.nodeValue;
}
na = parseInt(bstr,2);
sdna = sdnx(na,tgttd[1].firstChild.nodeValue);
tgttd[bits+1].firstChild.nodeValue = sdna;
tgt = document.getElementById("calb");
tgttd = tgt.getElementsByTagName("td");
bstr = "";
for (var i=1;bits>=i;i++){
bstr += tgttd[i].firstChild.nodeValue;
}
nb = parseInt(bstr,2);
sdnb = sdnx(nb,tgttd[1].firstChild.nodeValue);
tgttd[bits+1].firstChild.nodeValue = sdnb;
tgt = document.getElementById("calc");
tgttd = tgt.getElementsByTagName("td");
bstr = "";
for (var i=1;tgttd.length>i;i++){
tgttd[i].firstChild.nodeValue = " ";
tgttd[bits+1].style.backgroundColor = "#ffffff";
}
}
function doadd(){
var nsum = na + nb;
var tgt = document.getElementById("calc");
var tgttd = tgt.getElementsByTagName("td");
var bstr = "0000000" + nsum.toString(2);
bstr = bstr.substring(bstr.length-bits);
//tgttd[0].firstChild.nodeValue = bstr;
for (var i=1;bits>=i;i++){
tgttd[i].firstChild.nodeValue = bstr.substring(i-1,i);
}
var nc = parseInt(bstr,2);
var sdnc = sdnx(nc,tgttd[1].firstChild.nodeValue);
var truthsum = parseInt(sdna,10)+parseInt(sdnb,10);
var bgcolor = "#ffffff";
if (sdnc != truthsum){
bgcolor = "#ffcccc";
}
tgttd[bits+1].firstChild.nodeValue = sdnc.toString(10);
tgttd[bits+1].style.backgroundColor = bgcolor;
tgttd[bits+2].firstChild.nodeValue = truthsum.toString(10);
}
window.onload = function() {
setlistner();
}
function setlistner(){
var tgt = document.getElementById("cala");
var tgttd = tgt.getElementsByTagName("td");
for (var i=1;bits>=i;i++){
tgttd[i].onclick = function(){flip(this);}
tgttd[i].className = "bittd";
}
tgt = document.getElementById("calb");
tgttd = tgt.getElementsByTagName("td");
for (var i=1;bits>=i;i++){
tgttd[i].onclick = function(){flip(this);}
tgttd[i].className = "bittd";
}
tgt = document.getElementById("calc");
tgttd = tgt.getElementsByTagName("td");
for (var i=1;bits>=i;i++){
tgttd[i].className = "anstd";
}
}
</script>
<table id="addtbl"> <tr> <th></th> <th colspan="8">内部表現</th> <th>符号つき整数<br>(十進数)</th> <th></th> </tr> <tr id="cala"> <td></td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td> </td> </tr> <tr id="calb"> <td>+)</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td>0</td> <td> </td> </tr> <tr id="calc"> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> <td> </td> </tr> <tr> <td> </td> <td class="incdec" colspan="8"> <button type="button" onclick="doadd()">加算実行</button> </td> <td class="info">計算値</td> <td class="info">正しい値</td> </tr> </table>
#addtbl{
margin:1% 2%;
border:none;
border-collapse:collapse;
}
#addtbl td, #addtbl th{
border:none;
}
#cala td, #calb td, #calc td{
font-family:courier,monospace;
font-size:200%;
text-align :right;
padding:2px 8px;
height:1.5em;
}
td.incdec{
padding:16px 2px 1px 2px;
text-align :center;
}
td.info{
padding-left:1em;
text-align :right;
}
#addtbl td.bittd{
cursor:pointer;
border:solid 1px #999999;
background-color:#f0f0ff;
}
#addtbl td.anstd{
border:solid 1px #999999;
}
#addtbl tr#calc{
border-top:solid 1px #999999;
}
button{
cursor:pointer;
min-width:5em;
}