負の整数を含む足し算(8ビット)

負の整数を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-2254
11111101-3253
11111100-4252
11111011-5251
......
10000010-126130
10000001-127129
10000000-128128
01111111127127
01111110126126
......
0000100199
0000100088
0000011177
0000011066
0000010155
0000010044
0000001133
0000001022
0000000111
0000000000
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
01111111127-129
01111110126-130
......
000001106-250
000001015-251
000001004-252
000000113-253
000000102-254
000000011-255
000000000-256

プログラムなど

詳しい説明は4ビットを見てください。

Javascript

<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>

html部分

<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>

css部分

#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;
}