読者です 読者をやめる 読者になる 読者になる

ポジティブ心理学研究所

幸福度(EQ)アップの研究所です。ポジティブ心理学に出会う前の古い記事はネガティブなので注意。

【レビュー】プログラムはなぜ動くのか第2版

読書 プログラミング レビュー

プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識

プログラムはなぜ動くのか 第2版 知っておきたいプログラムの基礎知識

これはプロならずとも趣味程度でプログラミングを嗜む人間でも触れていても損のない、良書だと思いました。
CPUの仕組みから、配列やキューの概念、圧縮のアルゴリズム、アセンブリなどプログラミングに関する技術のひと通り解説があってコンピュータへおn理解を深めるのに最適な一冊と言えます。

以下内容の紹介。

第1章 プログラマにとってCPUとはなにか

CPUのレジスタやプログラムの流れ、アセンブリのことなど、以降の章で詳しく解説するものをこの章で軽く紹介しています。

第2章 データを2進数でイメージしよう

2進数とはなにか、シフト演算、論理右シフトと算術右シフトの違い、コンピューターは2進数でどのようにしてマイナス(負)の値を表現しているか、NOT、OR、AND、XOR等の論理演算等について解説されています。

2進数での負の値の表現

8ビットあるうちの先頭のビットを符号を表すビットとして、符号ビットが1かどうかで負の数かどうかを表現しますが、それだけでは十分ではありません。

例えば2進数00000001は10進数で1ですが、符号ビットを1にした10000001は符号ビットがマイナスで一番右が1なので-1ということにはなりません。

では-1は2進数においてどうやって表現するのか、それを解説しています。

また数値同士の加算(足し算)と減算(引き算)についても、コンピューターがどのようにして行っているのかも解説しています。

第3章 コンピュータが小数点数の計算を間違える理由

コンピューターは正確無比で計算は絶対に間違わない。というのが一般的ユーザーのおおよその理解かと思われます。しかし次の計算を見てみましょう。

0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 = 1

これは0.1を10回足しただけの簡単な計算です。0.1が10回なので答えは当然10倍の1となります。
これくらいは人間でも正確で確実な計算ができますが、コンピューターにやらせるとどうなるでしょう。

これはプログラミング言語であるJavaScriptで行った簡単な計算です。

> a = 0.1
0.1
> a += 0.1
0.2
> a += 0.1
0.30000000000000004
> a += 0.1
0.4
> a += 0.1
0.5
> a += 0.1
0.6
> a += 0.1
0.7
> a += 0.1
0.7999999999999999
> a += 0.1
0.8999999999999999
> a += 0.1
0.9999999999999999

一番最初にaという変数に0.1を代入した後、その数値に0.1づつ足しています。 もう3回目の計算でおかしいことが見てとれます。

そして10回目の加算で出た答えは1ではなく0.9999999999999999となりました。

また、これはJavaScriptだけでなく、別の言語でも同様の現象になります。
次の例はRubyで同様のことをした例です。

irb(main):001:0> a = 0.1
=> 0.1
irb(main):002:0> a += 0.1
=> 0.2
irb(main):003:0> a += 0.1
=> 0.30000000000000004
irb(main):004:0> a += 0.1
=> 0.4
irb(main):005:0> a += 0.1
=> 0.5
irb(main):006:0> a += 0.1
=> 0.6
irb(main):007:0> a += 0.1
=> 0.7
irb(main):008:0> a += 0.1
=> 0.7999999999999999
irb(main):009:0> a += 0.1
=> 0.8999999999999999
irb(main):010:0> a += 0.1
=> 0.9999999999999999

なぜこんな単純な計算を正確に計算できないかというのは、コンピューターが2進数しか扱えないことと、2進数で小数点をどのようにして表現しているかということに関係しています。

第3章では上記のことについて解説しています。

第4章 四角いメモリーを丸く使う

抽象的な題名ですが、本章ではスタックやキュー、そして二分木探索という配列に関する技術やアルゴリズムが紹介・解説されています。

配列を普段何気なく使っていても、それを実現している効率的な実装や技術等は知らなかったので非常に参考になった章です。

第5章 メモリーとディスクの親密な関係

ディスクキャッシュ仮想記憶、DLL(ダイナミックリンクライブラリ)がメモリーを節約するために関数を共有していることなどについて解説しています。

また、ハードディスクの物理構造についても触れ、記録方式であるセクター方式、バリアブル方式などについても解説しています。

第6章 自分でデータを圧縮してみよう

zipやlzhなどの圧縮されたファイルを我々は日常的に触れていますが、それがどのように行われているかについては知らないユーザーが大多数でしょう。

この章では、データを内容と繰り返し回数で圧縮する単純な方法であるランレングス法と、それよりもさらに効率のいい圧縮ができるハフマン法ついて解説しています。

国内で利用者の多い、有名圧縮ソフトLHAもハフマン法を使用しています。

ランレングス法は名前は知らないまでも、自分でもうっすらと考えてたことがあるのですがハフマン法についてはまったく思いつきもしなかったので、世の中には頭がいい人がいるもんだと思いました。

以後の章

以後の章については割愛しましが、それぞれこのような見出しとなっています。

  • 第7章 プログラムはどんな環境で動くのか
  • 第8章 ソースファイルから実行可能ファイルができるまで
  • 第9章 OSとアプリケーションの関係
  • 第10章 アセンブリ言語からプログラムの本当の姿を知る
  • 第11章 ハードウェアを制御する方法
  • 第12章 コンピュータに「考え」させるためには

どの章も、コンピュータへの理解を深めるのに役立つ情報ばかりです。

総評

この本は2007年に出された本ですが、コンピュータの電気的特性や低レイヤーの部分等は時代によって大きく変わるものでもなく、今でも十分にコンピュータの基礎的なことを学べる内容となっています。

特にスタックとキューや、二分木探索については目から鱗が落ち、ハフマン法についても感嘆し、そうだったのかと頭がスッキリしました。
ハフマン法は可逆圧縮技術ですが非可逆圧縮であるJPEGにも一部ハフマン法が使用されているそうです。

またディスクのセクターについての理解も深まり、ツイッターの開発しているCSSフレームワークであるBootstrapの語源もディスクとOSについての章で初めて知り合点が行きました。

プログラムをかじる人間にとっても、そうでない一般ユーザーにとっても、内部の仕組みを知ることはコンピューターを扱う上で役立つし、現代機器を扱う万民にとって非常に有用な本であると思います。

関連する記事「これからプログラミングを始める人へ、私がプログラミングを始める時にしたこと」もご覧ください。

その他押さえておきたい書籍

コンピュータはなぜ動くのか?知っておきたいハードウエア&ソフトウエアの基礎知識?

コンピュータはなぜ動くのか?知っておきたいハードウエア&ソフトウエアの基礎知識?

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識

ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)