整数型
Created by Masashi Satoh | 12/09/2025
はじめに
本記事は「データモデルの学び」を補強するものです。
レンジ
まず整数型の学びの導入として、生徒たちにレンジの話をするとよいでしょう。ビット数ごとに扱える数の最大値に目を向けるのです。特定のビット数で表現できる数値の上限が、ビット数の増加とともに倍々ゲームで増加していく様子は、私たちに驚嘆の感情を呼び起こします。二進法の明快さが、この学びの面白さを引き立てます。
- 1bit : 1
- 2bit : 3
- 3bit : 7
- 4bit : 15
- 5bit : 31
- 6bit : 63
- 7bit : 127
- 8bit : 255
- 9bit : 511
- 10bit : 1023
- 11bit : 2047
- 12bit : 4095
- 13bit : 8191
- 14bit : 16383
- 15bit : 32767
- 16bit : 65535(6万5千)
- 17bit : 131071
- 18bit : 262143
- 19bit : 524287
- 20bit : 1048575
- 21bit : 2097151
- 22bit : 4194303
- 23bit : 8388607
- 24bit : 16777215(1,680万)
- 25bit : 33554431
- 26bit : 67108863
- 27bit : 134217727
- 28bit : 268435455
- 29bit : 536870911
- 30bit : 1073741823
- 31bit : 2147483647
- 32bit : 4294967295(43億)
- 33bit : 8589934591
- 34bit : 17179869183
- 35bit : 34359738367
- 36bit : 68719476735
- 37bit : 137438953471
- 38bit : 274877906943
- 39bit : 549755813887
- 40bit : 1099511627775(1兆)
- 41bit : 2199023255551
- 42bit : 4398046511103
- 43bit : 8796093022207
- 44bit : 17592186044415
- 45bit : 35184372088831
- 46bit : 70368744177663
- 47bit : 140737488355327
- 48bit : 281474976710655(280兆)
倍々ゲームという言葉の通り、ビットが増えるごとに爆発的に扱える数値のレンジが増大していくのを確認するだけで、生徒たちにはとてもエキサイティングな経験となります。大きな紙を何回二つ折りにできるかという遊びを、あわせてやってみるのもよいでしょう。
取り扱う情報に見込まれるレンジをあらかじめ見通した上で、メモリー上に場所を確保することの重要性について生徒に言及します。メモリーは有限なので、無駄に大きな場所を占めることは避けるべきです。
メモリーが余白を持たないマス目のようなものだと理解すると、計算結果が用意したレンジをオーバーした場合にどうなるのかという問いが浮かぶはずです。
オーバーフロー
加算や乗算の結果がレンジを越えてしまったときに発生するオーバーフロー・エラーについて考察することはよい学びです。エラー処理を理解することで、コンピュータと人間の関係性が明確になるからです。
まず行うべきは、紙の上の筆算とメモリー(レジスター)上で行われる計算の違いを明確にすることでしょう。
紙の上の計算なら、結果の桁数が増えただけ紙の余白に書き込んでいくことができますが、メモリーという厳密に区画された媒体の上で行われる計算では同じようには行かないということです。これをイメージできることが重要です。
以下の図のように、_のひとつが1bitのメモリーだとします。加数、被加数、結果のそれぞれに3bitが割り当てられているとすると、これをそのまま計算すると1が失われてしまいます。
110
+010
=___ ⇒ 1000
紙の上での計算なら、余白にどんどん書き足していけばよいわけですが、数値を固定長の入れ物に入れて扱うコンピュータでは、このようなケースへの対処方法をあらかじめ設計者が考えておく必要があります。想定を越えた処理をコンピュータは自ら解決することができないため、人間が介入する必要がそこで生じるわけです。
これにはいろいろな対処方法があります。オーバーフローフラグの仕組みを設けて、計算を継続させる手法に触れるとともに、エラーを発生させて人間に対処を求めるというやり方にも触れます。生徒たちには、なんらかのインタープリター言語で、エラーが発生する様子をデモンストレーションして見せてもよいでしょう。
これはとても興味深い経験です。予定調和的なコンピュータの動作がエラーによって停止するその瞬間に、コンピュータの創造主が誰なのかが露わになるからです(もちろんそれは人間の精神活動です)。
コンピュータの実行プロセスそれ自体は、決定論に支配された閉じた系です。初期状態が決定されれば、後は定められた結果に向けてひた走ることしかできません。コンピュータはサイコロを振ることができないのです。
その証拠に、多くのプログラム言語には乱数を発生させる関数が備わっており、一見ランダムに見えるパターンを発生させることができますが、偶然性の種をその系の外側から提供しない限り、何度繰り返しても同じパターンを発生させることしかできません。
コンピュータがあたかも生き物のような振る舞いを見せるのは、コンピュータという閉じた系に対し、外部から現実世界の情報がインプットされたり、現実世界の時間に同期して割り込みが発生したりすることに基づいています。
AIが人間のように振る舞うのも、AIが大量に蓄積・整理した情報源が「人間らしさ」の体系を有しているからに他なりません。これが、自分自身のなかに意図をもち、無限に開かれた精神世界を内包している人とコンピュータを区別する決定的な違いなのです。
このように考えると、エラーがコンピュータの閉じた系の破れ目のようなものであり、コンピュータの本質が人間の前に露わになる機会だということが納得できるでしょう。
コンピュータがさまざまな機器の制御に使われるようになり、その制御プログラムに隠れていたミスのために大事故が起きるようになりました。そのような事故のなかでも、オーバーフロー・エラーによって起きた事故があります。1996年に欧州宇宙機関のアリアン5ロケットが起こした事故です。巨額の資金を投じて打ち上げ後わずか40秒足らずで、積載した衛星もろとも爆発した惨事です。
加速度計の数値を受けてエンジンを制御するプログラムが、扱う数値が16bitの整数のレンジに収まるという想定でつくられていたところに、そのレンジを越える数値が送られてきたために、オーバーフローを起こしたのが原因だったと伝えられています。
たったこれだけのエラーが重大事故を起こす。オーバーフロー・エラーの学びの際に、ぜひ触れておきたい話題です。
この事故の資料は豊富で、動画映像も公開されているので、授業準備の取材源に事欠きません。ヴァルドルフ教育は安易な実物教育とは一線を画します。生徒に動画を見せたりせず、ぜひ、自分が見てきたかのように先生が生き生きと物語ってください。
*この事例は愛知シュタイナー学園でこの授業に取り組まれた浅井英臣さんに教えていただきました。この場で感謝申し上げます。
負の整数の表現方法と四則演算
では、次のステップに進みましょう。
単刀直入に生徒に質問します。「ここまでは正の数の扱いについて考えてきました。では、コンピュータで負の整数を扱うにはどうしたらよいでしょうか?」
「リレーによる加算機回路製作の詳細」の学びで、2の補数については簡単に触れましたが、これが負数の表現として用いられていることにまでは立ち入りませんでした。ですから、生徒からはいろいろな考えが出てくるでしょう。
「-1」、「-250」のように、正負の情報を数の情報とは別にもつというのも悪くない考えです。実際に、この方式のモデルを生徒とともに考えてみるとよいでしょう。たしかにこれはわかりやすく、しっかり機能します。
しかし、実際のコンピュータでは、この方式はほぼ用いられません。その理由は、黎明期のコンピュータでは利用できるメモリの量が限られていたため、できるだけコンパクトに情報を扱うことが至上命題だったこがにあります。また、計算装置のコストを最小化することも考えなければなりませんでした。
そこで考えられたのが、2の補数による負数の表現です。
2の補数による負数表記
2の補数については数多くの解説がありますが、2の補数とは2を基数とする補数のことで、元の数に足すと桁上がりする最小の被加数のことだと説明されています。合同式との関連に触れている解説もあります。どこまで踏み込むかは、数学の学びとの連携で考えればよいと思いますので、数学の先生と相談するのがよいでしょう。
ここでは最低限、以下の事柄が網羅されればよいと思います。
- 有効桁数を固定した上で、加数と足し合わせてオーバーフローしたビットを切り捨てると、減算の結果が得られる性質をもった負数の表現形式であること。
- 最上位ビットが1となるため、正負の区別が容易であること。
- 正の数だけを扱う場合に比較して、同じビット数で表現できる数は約半分になる。
- 減数の全ビットを反転し、有効桁数を固定した上で1を加え、オーバーフローしたビットを切り捨てるという簡単な操作だけで2の補数が得られること。
もし余力があれば、次のような話をしておくとプログラミングの学びの際に役立つと思います。
- ブール型の存在に触れ、その実体が整数値であることを解説する。
プログラムの処理系の多くは1を真、0を偽とするが、なかには全ビットを1としたものを真、全ビットを0としたものを偽として扱うものもあります。後者の真値は、数値にすると2の補数表現で-1となるのが面白いと思う生徒もいるでしょう。
それぞれの処理系の設計者が、なぜそのような仕様にしたのかを生徒たちに考えさせるのもよいでしょう。自分ならどうするでしょうか。なかには、二値情報の保持のために1ワード消費するのはもったいないから、1ビットずつ管理したほうがよいと言い出す生徒もいるかもしれません。
実際に低レベルのインターフェイスなどでは、フラグ情報として1ワード中に複数のブール情報を保持する例は数多く見られます。そのようなフラグ情報の特定の値の真偽を判定するためには、どのような手続きが必要かを考えさせます。
ABCDEXYZ
その特定のビットに対応するマスクパターンを用意してANDをとり、その結果が0か否かでフラグが立っているかどうかを確認するわけです。
ABCDEXYZ
00000100 AND
00000X00
書き込むときはさらに面倒な手続きが必要です。書き込むフラグの値が0であれば、該当するフラグのビットのみ0で残りの全ビットが1のパターンを用意し、現状のフラグセットとのANDをとってその結果を書き込みます。
ABCDEXYZ
11111011 AND
ABCDE0YZ
1であれば、該当するフラグのみ1のパターンを用意して、今度はORをとるというように。
ABCDEXYZ
00000100 OR
ABCDE1YZ
この作業コストをどのように考えるのか、話し合うのもよいでしょう。
上記4の方法に関しては、「リレーによる加算機回路製作の詳細」の「コンピュータシステムの全体像」の項で簡単に説明しました。ここで丁寧に説明し直してもよいと思います。
上記1の性質を用いて、加算の仕組みで減算が可能になります。というより、この性質があるゆえに、2の補数が整数型の負数表現として定着したわけです。2の補数の細かい議論に首を突っ込むよりも、このニュアンスが伝われば十分でしょう。
ブール型の真値の内部表現を-1として保持する処理系としてよく知られているのは、マイクロソフト社のBASIC言語からの派生言語です。ExcelやWordにもVBAが実装されているので、簡単に確認してみることができます。
VBAの開発環境VBEを呼び出して、イミディエイト・ウインドウを開き、以下のコードをタイプしてみてください。
a=True debug.Print a True debug.Print CInt(a) -1 debug.Print Hex(a) FFFF a=False debug.Print CInt(a) 0
四則演算、比較と条件処理
減算の仕組みが手に入ると、四則演算すべてが可能になります。その際に、シフト演算について触れておくとよいでしょう。左方向(大きい桁の方向)に全情報を1ビット分ずらし、最下位桁に0をおぎなうと、二進法の世界では2を乗じたのと同じ結果が得られます。反対方向では逆の効果が得られます。
これを左シフト、右シフトと呼び、これを使って乗算と除算を行います。浮動小数点型の正規化手続きでも大活躍するので、しっかり説明します。以前、加算機につないだシーケンサーで遊んだ経験のある生徒なら、シフトの動作をリアルにイメージできることでしょう。
手持ちの時間に応じて、乗算と除算の手順をおさらいします。
とくに除算では、減算した結果が負にならないかどうかを試行する作業が発生するので、減算を仮に行うことで比較が行えることを丁寧に説明します。結果がゼロであるか否かは、結果のすべてのビットのORをとればわかります。正負については、ただ結果の最上位ビットが1か0かを見るだけでわかります。1なら負です。
その結果に応じて次の処理の手順を切り替える仕組み、条件処理の仕組みが作られていることにも言及します。
このような低レベル処理を丁寧に追いながら、コンペアや条件処理の仕組みを学ぶことで、プログラミングの学びの際にもコンピュータの陰の動作をイメージすることができるでしょう。コンピュータをブラックボックス化しないために、これは重要です。とくに条件処理を「判断」という概念で理解することへの予防線となります。
コンペアのプロセスで起きている出来事は、減算の結果が0、または正であるか負であるかということだけであり、その結果により事後の手続きを切り替える仕組みは、列車の線路のポイントを切り替える仕組みと何ら変わりはありません。その条件処理の結果による後続の手続きの意味は、そのプラグラムを作った人間の意図に属しており、走っている列車自体はそのことには何ら関与しないのです。
判断しているのは、プログラムを思考実験でテストしているプログラマーその人だということです。
くどいようですが、このポジションこそが高度なICT技術の津波を前にしてわたしたちが正気を保つための強固な地盤なのです。
除算に関しては、0による除算でエラーを発生させる処理が必要であることにも触れましょう。
そして、剰余演算についても取り組みます。剰余演算は、偶数奇数の判定や、曜日の判定など、数値から周期性をもつ情報を引き出すためにしばしば用いられます。
また、画面の座表面に斜め線をなめらかに引きたい場合に、剰余演算を用いると、整数演算だけで線の勾配の座標補正を行うことができます。それがどうしてなのか考えながら、実際にプログラムを組んで、線を引いてみるのも面白いでしょう。
2の補数表現について、その数学的な背景も含めた解説はたくさんありますが、わたしには以下の資料がたいへん参考になりました。
IDとしての整数
整数はIDとして用いられることが多々あります。
ただし、その本質は、重複のない一意のパターンとして用いられているということであり、数として用いられているのではないことをしっかり押さえておきます。
コンピュータは概念を直接操作することができないため、人間が特定の概念とIDを結びつけ、概念とIDの関連に基づいてつくられたプログラムによってIDというパターンを処理し、その結果のパターンを人間がふたたび概念と結びつけて活用するのです。
その意味では、整数型自体がそもそもIDであるわけです。整数という概念を二進数と一致するパターンに付与した結果、そのパターンに序数としての性格があらためて付与されたわけです。これは興味深い発見です。
つまり、人間はあらゆる概念をIDという記号に託してコンピュータに入力し、それらを人間世界の概念の相関関係に沿って処理する手順を用意しコンピュータに実行させます。
しかしコンピュータには、それらのID群がどんな概念と結びついているのかを知る手段はありません。コンピュータはただ、示された手順書通りにそれらのID群を処理するだけのことです。その結果が何を意味しているかに関わることもありません。ただ淡々と結果を人間に返すだけです。
どんなに高度なAIと言えども、その例外ではありません。
整数の数理的な性質がもっとも役立つのは、IDを序数のスタイルで扱い、一意であることを保証しながら新たなIDを追加する仕組みを作る場合でしょう。
生徒たちに、「ランダムなパターンを発生させて、それらが重複しないことを保証するにはどうしたらいい?」と問うてみましょう。すぐにそれがたいへんなことだと気づくはずです。しかし序数であれば、発行した数値の最大値を記録しておけば、確実に重複を回避できるわけです。ここでは整数を用いたIDの数値としての性格が役に立ちます。
様々な概念を固定したIDと結びつけて規格化するような用途でも、IDが序数であることが意味をもちます。その典型が文字コードです。文字コードについては次項で詳しく取り上げます。
また、ポインター型もある種のIDと見ることができるでしょう。IDが具体的なアドレスの値であること、変数であるという特徴があるという特殊性がありますが、パターンが具体的な対象を指すという意味ではID的用法です。
一意の記号を使って現実世界の概念を操作するIDに対し、ポインター型は番地情報という記号を使ってメモリー上の情報ブロックを動的に操作するという点で、よく似ています。
次項の浮動小数点型に続いて次々項では文字型・文字列型を扱いますが、文字列型の学びのなかでポインターを用いた文字列操作を扱いますので、ここで先取り的にポインター型の概要に触れておく必要があるのです。
生活、太陽や星々の運行と結びついたDateTime型
最後に、シンプルな整数型がわたしたちの生活、そして星々の運行に結びついたDateTime型として応用されていることに触れられたら素晴らしいと思います。
この型自体はただの整数値ですが、オーバーフロー・エラーと同様に、コンピュータという閉じた系と開かれた世界との接続を考える上で非常に重要な役割を負っています。
コンピュータの内部で働いているロジックは、わたしたち人間が体験している太陽や星々の運行と結びついた時間とは独立した時間のなかで動いています。クロックの指示に従って1ステップずつ進行していくプロセスは、独自の「プロセス時間」と呼びうるような固有の時間であり、そのロジックが人間の時間と関係をもつことは原理的には不可能です。なぜなら、コンピュータのクロック信号は、リアルな世界とはなんの関わりももたない、ただプロセスを統御するためだけのエゴイスティックなインパルスだからです。
もっと言えば、コンピュータはそもそも、進行するプロセスの状態遷移の前後の関係について、何も知らないのです。ただ、指示された目の前のインストラクションを遂行するだけです。コンピュータは変化を理解せず、因果関係を理解せず、よって時間に関わることがありません。
わたしたちがコンピュータのモニターのなかに見ているものはすべて、目隠しをされた馬のようにコードのトラックを爆走したコンピュータがメモリー上に残した轍(わだち)、すなわちメモリー上のパターンであるということにわたしたちは気づく必要があります。コンピュータ自体にとって、それは意味をもちません。そこに意味を見いだしているのは、そのパターンと特定の概念を結びつける人間の精神なのです。
そのような世界に、最初に持ち込まれた人間的な要因がリアルタイムクロックです。閉じたコンピュータの系に、現実世界の時間に同期した割り込みをかける仕組みを付け加えることによって、コンピュータのプログラムは現実世界の時間に応答したプロセスを提供することができるようになります。この仕組みによって、プログラマーは、時間軸という尺度のなかで「今」をプログラムで処理できるようになります。
では、DateTime型はどのように時間概念を表現しているのでしょうか。それは、それぞれのシステムの設計者が、そのシステムで扱うリアルな歴史時間の起点を任意に決めることから始まります。
もっとも普及しているUNIXタイムでは、協定世界時(UTC)における1970年1月1日午前0時0分0秒を起点にしています。この起点となる時間からの1秒ごとの経過を1ずつカウントした整数値を扱うための型が、UNIXシステムのDateTime型として用いられているわけです。
この時間の起点を決めたのは、神殿で神々の神託を司る神官でも王でもなく、UNIXシステムを開発していた科学技術者デニス・リッチー氏だったようです。インタビューに答えて、彼は次のように語っています。
「当時は、テープもなかったし。複数のファイルシステムが稼動していて、われわれは、元となる時間を常に変更していた」とリッチー氏は言う。「とうとう、『当分オーバーフローしないような起点を設定しよう』ということになった。1970年1月1日が一番よさそうに見えた」
WIRED 2000年問題は「問題なし」 1970年1月1日午前0時から10億秒目を刻むUNIX
このような、じつに世俗的な理由により、コンピュータ時間は創造されたのです。「時間の創造」という文脈でこの事実を語ることにで、ヴァルドル学校の生徒たちは多くのことを感じ取ることでしょう。
このカウントアップしていく単なる整数から、わたしたちの文化の成り立ちに沿って、年、月、日、曜日、時間、分、秒の数値を取り出す作業は、大理石の塊からキリストのかたちを掘り出すミケランジェロを彷彿とさせるものがあります。暦の文化のなかには、太陽や月の運行と通じ合っていた古代人の精神世界が生きているのです。わたしたちはここで、コンピュータの歴史の冒頭で出会った、アンティキテラ島の機械を作ったギリシャ人の世界観とふたたび出会います。
さて、こうしてDateTime型の基本的な考え方を理解した上で、もしも時間があれば、ややこしい日付の計算に取り組んでみるとよいでしょう。たとえば、登録日に年齢だけわかっている人が、数年後の任意の日に何歳になっている可能性があるのかなど、時間を数の概念で捉えることの意外な難しさに取り組んでみるのはよい経験です。
- ヴァルドルフ/シュタイナー教育におけるICTカリキュラムの骨格を形づくる
- The History of Computers(Currently being produced)
- リレーによる加算機回路製作の詳細
- シーソーによる論理素子
- クロックとメモリー
- リレーの起源と電信装置
- シーケンサーについて
- About the Battery Checker(Currently being produced)
- インターネット
- データモデルの学び
- Learning Programming and Application Usage Experience(Currently being produced)
- Human Dignity and Freedom in an ICT-Driven Society(Currently being produced)



コメント