1より小さい数を二進法で表す方法

固定小数点法で小数

整数部分8桁、小数部分8桁の二進法表現を十進法に換算するプログラムです。

クリックした桁の0-1が入れ替わって二進数が変化します。下の「合計」欄に十進法での表現が出て確認できます。

0から255.99609375までの値を0.00390625刻みで表現できます。もし、全部を整数と考えれば0から65535まで1刻みで表現できます。

2726 2524 2322 2120 2-12-2 2-32-4 2-52-6 2-72-8
00 00 00 00 00 00 00 00
12864 3216 84 21 1
2
1
4
1
8
1
16
1
32
1
64
1
128
1
256
合計 0

「コンピュータで小数を表す時は浮動小数点数で」と安易に決めつけないで、まず本来の二進法の小数を理解しましょう。

1に2を次々にかけた、1, 2, 4, 8, 16,... を逆にたどっていくと、16, 8, 4, 2, 1, で次々に2で割っていることになります。さらにこれを続けると、1/2, 1/4, 1/8, 1/16,...となっていきます。これが 2-n の値です。それらを合計したものが二進数の値です。

2-nの値でnが負の数の場合

2-nの値を10進の小数で表すと次のようになっています。整数より複雑です。

2進法では小数点以下1桁では0.5刻みになるなど表現が荒く感じられますが、整数でも2進法は桁数を多く必要とします。小数も桁数を多くすることで刻みを小さく出来ます。

十進分数 二進表現 十進小数
2-11
2
0.10.5
2-21
4
0.010.25
2-31
8
0.0010.125
2-41
16
0.00010.0625
2-51
32
0.000010.03125
2-61
64
0.0000010.015265
2-71
128
0.00000010.0078125
2-81
256
0.000000010.00390625

十進表記で見慣れた小数も二進表記ではその多くが循環小数になり有限桁では正確に表せません。

十進表現 二進表現
0.10.000110011001100…
0.20.001100110011001…
0.30.010011001100110…
0.40.011001100110011…
0.50.1
0.60.100110011001100…
0.70.101100110011001…
0.80.110011001100110…
0.90.111001100110011…

二進でも十進でも循環小数を有限桁で表現しようとすると不正確になるのは同じです。しかし十進の小数を二進で表現すると循環小数になることが多いということは、コンピュータに値を入力した段階から正確な値を入れたことになっていないということは、知っているべきかもしれません。

固定小数点方式

コンピュータで数を表現するときには、ほぼ固定小数点方式か浮動小数点方式です。

整数を表す場合は、多くの場合固定小数点方式を使いますが、だからといって、「小数点を右端に固定する方式である」と断言すると正しくありません。

浮動小数点方式を使う場合でも仮数部分は固定小数点方式の計算方法を利用しますので、固定小数点方式の小数に触れておくことも必要だと思います。

制作意図

小数がでてくるとさっさと浮動小数点数を紹介してしまうのではなしに、固定小数点方式でもできることを示そうとしたものです。きちんと理解できなくても、触れたことがあるということも大切だと考えています。整数までなら解りやすいと思ってもらえるかもしれません。「小数点を固定する」という名前の意味もわかります。

プログラムなど

2進法の時計の付録として整数の12ビットについてやったものとほとんど同じです。違う所は2つ。

(1)小数点を画面に加えるのをイベントハンドラの取り付けの時についでにやっています。

(2)高位のビットから下位へビットを加えて2倍するというのを繰り返して値を計算していましたが、マイナス部分で28分かけすぎているので、最後に256で割ります。

整数部2桁小数部2桁の場合で例を挙げるなら 22=4で割ります。

1011 ⇨ (((1x2+0)x2+1)x2+1 = 11
10.11 ⇨ { (((1x2+0)x2+1)x2+1 }÷4 = 2.75

javascript部分

<script>
window.onload = function() {
  tinit();
}
var tbtns,tflps,tsum;
var flpcolor = new Array("#ccc","#039");
function tinit() {
  var btnsrow = document.getElementById("tbtn");
  tbtns = btnsrow.getElementsByTagName("td");
  var flpsrow = document.getElementById("tflp");
  tflps = flpsrow.getElementsByTagName("td");
  for(var i=0; tbtns.length>i; i++){
     tbtns[i].setAttribute("onclick","tflip(this)");
  }
  tbtns[7].style.background="url(images/dotL.png) #f0f0ff bottom right no-repeat";
  tbtns[8].style.background="url(images/dotR.png) #f0f0ff bottom left no-repeat";
  tsum = document.getElementById("tsum");
  tcalc();
}
function tflip(tgt){
  tgt.firstChild.nodeValue = 1-tgt.firstChild.nodeValue;
  tcalc();
}
function tcalc(){
  var sum = 0;
  for(var i=0; tbtns.length>i; i++){
    sum *=2;
    var bit = Number(tbtns[i].firstChild.nodeValue);
    sum += bit;
    tflps[i].setAttribute("style","color:"+flpcolor[bit]+";");
  }
  tsum.firstChild.nodeValue = sum/256;
}
</script>

html部分

<table class="b16">
<tbody>
<tr class="pw">
<td>2<sup>7</sup></td><td>2<sup>6</sup></td>
<td>2<sup>5</sup></td><td>2<sup>4</sup></td>
<td>2<sup>3</sup></td><td>2<sup>2</sup></td>
<td>2<sup>1</sup></td><td>2<sup>0</sup></td>
<td>2<sup>-1</sup></td><td>2<sup>-2</sup></td>
<td>2<sup>-3</sup></td><td>2<sup>-4</sup></td>
<td>2<sup>-5</sup></td><td>2<sup>-6</sup></td>
<td>2<sup>-7</sup></td><td>2<sup>-8</sup></td></tr>
<tr id="tbtn">
<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>0</td>
<td>0</td><td>0</td>
<td>0</td><td>0</td>
<td>0</td><td>0</td></tr>
<tr id="tflp">
<td class="k3">128</td><td>64</td>
<td>32</td><td>16</td>
<td>8</td><td>4</td>
<td>2</td><td>1</td>
<td>1<br><span>2</span></td><td>1<br><span>4</span></td>
<td>1<br><span>8</span></td><td>1<br><span>16</span></td>
<td>1<br><span>32</span></td><td>1<br><span>64</span></td>
<td class="k3">1<br><span>128</span></td><td class="k3">1<br><span>256</span></td>
</tr>
<tr class="sum">
<td colspan="6">合計</td>
<td id="tsum" colspan="10">0</td>
</tr>
</tbody></table>

css部分

#tflp td{
  padding:2px 0;
  line-height:120%;
  text-align:center;
}
#tflp span{
  text-decoration:overline;
  padding:0 4px;
  /*border-top:solid 2px #000000;*/
}
.b16 {
  margin:1%;
  border:none;
}
.b16 td{
  text-align:center;
  border:none;
  padding:2px 0;
}
#tbtn td{
  font-size:150%;
  width:1.5em;
  height:2em;
  border:solid 1px #666;
  padding:2px 0;
  cursor:pointer;
  background-color:#f0f0ff;
}
.k4{
  font-size:75%;
  }
.k3{
  font-size:85%;
}
#tsum{
  font-size:150%;
  text-align:center;
  color: #000;
}
.sum td{
  border-top:solid 1px #99f;
}