2ntブログ

プログラマは10進数で考えてはならない

現在のノイマン型と呼ばれるコンピュータの基本構造では、プログラムもデータも、全て2進数で管理される。
2進数とは、0と1の2つの数値で1桁とする数の数え方だと思ってくれれば良い。
従って2進数の10は、我々が日常で使ってる10進数に直すと2になる。

なぜ2進数なのかと言うと、それが一番エラーが起きる確率が低いからだ。
0というのは、電流がまったく流れてない状態であり、1というのは電流が流れた状態である。
これを一定の間隔で発振(振動)する鉱物として知られ、時計などにも使われている水晶(クォーツ)によって一定のタイミングで、電流が流れたのか、流れなかったのかを記録したものが、2進数の数値データとして使われるのだ。
電流が流れたか流れてないかの2種類だけの判別のため、たとえば電池で動いているようなものでも、電池が切れ掛かって電圧が下がったりしても、正確に計算処理ができる。
これを例えば電圧なり電流の量(アンペア?)などを10段階で判別するようにして、10進数で内部的に扱う仕様にすると、電池が切れ掛かって電圧が下がった時に、正確な計算が出来なくなる。
なぜなら、0.2Vの電流が流れたら「2」とかって決まってるのに、電池が少なくて0.15Vしか流れなかったら、「2」として判別できなくなってしまうからである。
電池でなく、普通のコンセントから電源が供給されている場合でも、温度や湿度や、あるいはその他の外部的な要因によって、正確な10段階の表現ができなくなる場合もある。
だから、単純に電気が流れた・流れてないの2つだけで判別する2進数が使われるのだ。

さて、2進数では0と1の2種類の数値しか扱えない。
これでは人間界で役に立つ複雑な計算処理や、大量の数値データが扱えない。
よって、コンピュータ内部では2進数を8桁を一区切りとして扱う。

なぜ現代の世界で日常的に使われている10進数にしなかったのか?
それは2進数はどう変換しても、きっちり10進数にはならないからだ。

2進数では2以上の数値は桁数を増やさないと表現できない。
2進数2桁なら0・1・2・3まで。
3桁なら0~7まで。
4桁にすると0~15までとなり、どうがんばっても、ぴったり10にできる桁数が無いのだ。
だからコンピュータは16進数になっている。
ちなみに現代の現実世界でも、時計などは60進数である。
60秒で1分、60分で1時間と桁が上がっていくからだ。
(まぁ60時間で1日にならないのは、アレだがw)

16進数とは、1桁で0~15まで表せる数の数え方になる。
しかし今の世界で標準的に使われているアラビア数字には0~9の10種類の文字しかない。
なのでコンピュータの世界では10~15までの数値は、16進数ではA~Fまでのアルファベットを代わりに使って表現している。

そして更に16進数2桁で1バイト、つまり最小のデータ単位として扱うのが今のコンピュータの基本仕様である。
表記では00~FFまで、10進数だと0~255までの数値になる。
従って256以上の数値データを扱う場合は、メモリでもHDDでも2バイト使う事になる。

この計算が、10進数で物事を考えているとできないのだ。
だからプログラマは16進数で物事を考えろと言っている。

画面に表示する時は10進数にするにしても、内部の処理的な事は全て16進数で考えないと、無駄にメモリやHDDを消費し、また処理スピードもその分落ちる。

この仕様は、人間社会に「電卓」という形ではじめてコンピュータが登場して以来、インベーダゲームやファミコン、パソコン、Windowsの登場、そして現在のスマホのような超小型コンピュータが登場するまで、変わっていない。
スマホもPCもサーバ(業務用コンピュータ)も、全て1バイトが記憶領域の最小単位であり、1バイトは16進数2桁である。

関係ない豆知識をここでひとつ。

プログラマの世界では、「サーバー」は「サーバ」、「コンピューター」は「コンピュータ」、「データー」は「データ」と文章で使う時は表記する。
また、英数字は「半角文字」を使う。
別にこうしなきゃいけない決まりがあるわけではない。

これは恐らく、メモリやHDDなどの記憶領域が少なかった頃の名残だ。
極力、文字数を少なくする、全角に比べて、半角文字は1バイトで表現できるので、英数字など「半角」で表現できる文字は「半角」を使ったのだと思う。

話が逸れたが、コンピュータ創世記のプログラマってのは、そこまで拘ったのだ。
初代ドラクエが、容量の関係で「カタカナ」を50音ではなく、使用頻度の高い上位20音分しか文字グラフィックデータとして入れなかったという逸話もあるように、昔のプログラマは常に「メモリ容量」や「記憶領域」とのギリギリの戦いをしていたw

まぁ今の時代は、そこまでする必要はないわけだが、それでもやはり物事を16進数で考えないと、無駄に容量を使い、処理スピードを落とす事にはかわりない。

Visual BASICには、変数の型の定義に、「バイト型」ってのがある。
これはその変数の内容を記憶するのに、どれだけのメモリを確保するかという命令というか、開発言語への指定なわけだが、「バイト型」にすると、最小の1バイトだけしか確保されないので、その分容量が少なくなるし、処理スピードもアップする。
ただし0~255の数値、あるいはそれで表せるデータしか、その変数には入れられない。
私はループカウンタ(For~Next文で使う、ループ回数をカウントする変数)は、大抵はわざわざバイト型を指定した変数を使っていた。
実際それで、プログラムの処理スピードが1分も2分も変わるのかと言われれば、そこまでの差は出ない。
ただし塵も積もればという言葉があるように、それらが積み重なっていけば、確実に差は出る。

16進数で物事を考えるのは、処理スピードやメモリの節約のためだけではない。
コンピュータプログラムには「バグ」というものがつきものだ。
「バグ」というのは、単純な命令語のミスもあるが、一番多いのは「想定外」の処理がされた場合だ。

たとえば、商品の値段を記録する領域が、事前の発注元との打ち合わせで、「最大でも100万円未満の商品しかうちは扱わないので、そういう仕様で作ってくれ」ってなってたのに、実際には100万円を超える商品を扱い始めてしまったという場合、当然ながら、それをそのまま入力したり処理したりすれば、不具合が起こる。
「オーバーフロー」と呼ばれる現象だ。
日本語に訳すと「桁あふれ」。

予め用意されていた保管領域内で管理できない数値が入力された事で、誤った数値になってしまって、それで計算されてしまうのだ。

1バイトで定義されている変数に、256以上の数値を入れたら、コンピュータの内部ではどうなるか?
答えは本来必要になるはずの3桁目が切り捨てられ、下2桁のみ反映される事になる。
たとえば256という10進数を、1バイトしか用意されてない変数に入れると、その変数の中身は0になる。
コンピュータ上では16進数2桁が1バイトであるが、256という10進数の数値は16進数だと100となる。
だが3桁目が無いので、「1」の部分は切り捨てられ(正確にはオーバーフローフラグというものが、専用のフラグレジスタに立つのだが)、下2桁の「00」の部分だけが、メモリやHDDに反映される。
これで計算したら、計算結果がおかしくなるのは当たり前だw

しかしこういった不具合の原因も、16進数で普段からプログラムやデータを考えてないアホだと気づかない。
なぜなら、例に出した100万円という数値は、16進数だと「F4240」となり、3バイト使わないと表現できない。
だが99万9999円も、同じく16進数だと「F423F」で3バイト使う。
よって設計段階で、最大99万9999円の「値段」が保管できれば良いとなっていれば、データ領域は3バイト確保されており、もし仮にそれで何か不都合が生じても、少なくともオーバーフローではない事が分かる。
この設計での「値段」の上限は、プログラム内部的には、「FFFFFF」を超える数値、すなわち10進数で1667万7215円を超える値段が入力されない限り、オーバーフローは起こらない。

もっとも、5桁しか使わないので、残り1桁がもったいないからと、別の符号なり何なりの領域として使用していたら、この限りではないが、1バイトの内部を1桁づつ別の用途に使うなんて高度なやり方は、そもそも16進数やコンピュータの基本仕様を理解し、さらにそれが可能な開発言語でないと出来ない。
そんな複雑かつ面倒な事は、ほぼ無限に記憶領域が使える現代のコンピュータシステムでは、普通はやらない。
容量がカツカツのファミコン時代のプログラマならともかく。

まとめると
・コンピュータというのは2進数で動作している
・それは一番エラーが発生する確率が低い方法だから
・データとして扱う場合、2進数8桁を最小の1バイトとして扱う
・これらをそのまま2進数8桁で表記すると、えらい文字数を使うので、16進数2桁としてプログラムの世界では表現する。
・従ってプログラマは16進数で物事を考えた方が良い

なお何かの業務システムにしろ、ゲームにしろ、実際にプログラムを動作して使う客やプレイヤーは10進数しか理解できない。
なので画面などに数値として出す場合は、10進数に直さなければならない。
16進数を10進数に直す計算は、Windowsならば「アクセサリ」の中にある「電卓」で簡単にできる。
「電卓」を起動したら、「表示」→「プログラマ」をクリック。
すると、通常は0~9までしかない数値ボタンにA~Fまでも文字が増え、更に2進・8進・10進・16進という変換スイッチが増えて表示されるようになる。
これで16進数で数値を入力した後で、変換スイッチを16進から10進に変更すれば、10進数での表記にそのまま変換される。
逆も可能。
Windowsマシンでプログラムやってる人で、もし知らない人が居たら、使ってみて下さいw

コメントの投稿

非公開コメント

カウンタ
プロフィール

ウホッ!いい男

Author:ウホッ!いい男
異世界転生を待ち続ける中高年のおっさん

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR