この章では、本書で学ぶことの概要と、前提とする知識について説明します。

1. 学ぶ内容

コンピューター科学は現代社会の基盤技術となり、人工知能、SNS、スマートフォン、自動運転など私たちの生活のあらゆる側面に影響を与えています。本書では、日常的に使っているデジタル技術の背後にある原理を探求し、コンピューターの仕組みや情報の本質について学びます。文系・理系を問わず、デジタル社会を生きる上で役立つ知識と視点を身につけることを目指します。

  • コンピューター内部でのデータの表現方法について理解する

  • 文書、画像、動画等のデータ量の感覚を身につける

  • コンピューターでの複雑な処理が基本演算から構成されていることを理解する

  • コンピューターに関連した技術や理論の広がりについて理解する

本書は、道具としてのコンピューターの操作を学ぶことが目的ではありません

普段使っている Microsoft Office や Windows、macOS 等の操作方法を学ぶための本ではありません。

「コンピューター」を「自転車」に置き換えてみると、

  • 自転車に乗れるように練習する

ための本ではなく

  • 自転車はどのような構造になっているのか

  • 自転車はどのような仕組みで倒れずに進むのか

を、背後にある物理法則や工学的な原理を通して学ぶ本であると考えてください。

「コンピューター科学」は「計算機科学」ともいいます。ここでいう「計算機(computer)」は電卓の「計算器(calculator)」ではなく、コンピューターのことを指します。つまり、ここでの計算(computation)とは狭義の計算(calculation)とは異なります。たとえば、人間の知的活動を計算(computation)としてとらえるのが人工知能の考え方です。

高校数学の数学I・A・II・Bの知識を前提として説明をすすめます(読み進めるうちに思い出せる程度で十分です)。

本書の内容は、短期的にすぐに役に立つ内容ではないかも知れないという点は強調しておきます。

ただし、国家試験である情報処理技術者試験の「基本情報技術者試験」と「応用情報技術者試験」の受験を考えている読者にとっては、出題される一部の範囲の内容を含んでいるので、受験勉強に役立つかもしれません。受験参考書には書かれていない原理などについてより深く学ぶことができます。

なお、基本情報技術者試験は2023年4月からCBT方式による通年実施となり、出題も科目A・科目Bに再編されています。以下はWikipediaの 基本情報技術者試験 からの引用です(再編前の時点の記述を含みます)。

新卒のIT職の志望者の中での取得率は10%に満たない。大手民間企業や公的機関のIT関連職では基本情報技術者試験 (FE) 以上の合格者しか採用しないケースもある。 公的機関では特に、情報技術の関連職の採用を、基本情報技術者試験 (FE) の合格を基準に行っているところがあり、大学卒業程度に相当する資格と位置づけられるのが一般的である。

1.1. 本書で扱うトピック

本書では、広いコンピューター科学のトピックから以下の内容を選び、基本的な考え方を学びます。各章は次の問いに答える形で進みます。

表 1. 本書の章と、各章で考える問い
章 内容 考える問い

2

コンピューター発展史とデータの単位

コンピューターはどのように小さく速くなってきたか。「ギガ」とは何の量か

3

数の表現

負の数や小数を0と1でどう表すか。なぜ計算に誤差が出るのか

4

文字の表現

文字はどんな番号で表され、なぜ文字化けが起こるのか

5

フォント

画面や紙の上の文字の形は、どのように作られ選ばれるのか

6〜8

論理回路・ブール代数・順序回路

0と1の単純な演算から、計算や記憶の仕組みがどう作られるのか

9

情報理論

情報の量をどうはかり、どこまで圧縮や誤り訂正ができるのか

10

アルゴリズムと計算量

同じ問題を、より少ない手間で解く手順とは何か

11

停止性問題

コンピューターでは原理的に解けない問題があるのはなぜか

12〜13

P≠NP予想とNP完全性

答えの検算が簡単な問題は、解くのも簡単なのか

以下、それぞれの内容を簡単に紹介します。

1.1.1. コンピューター発展史とデータ量の単位(第2章)

電子式コンピューターの歴史は1940年代の真空管を使った初期のコンピューターから始まり、トランジスタ、集積回路、そしてマイクロプロセッサへと発展してきました。この発展の過程で、コンピューターの性能は飛躍的に向上し、サイズは小型化してきました。

スマートフォンで大量の動画などをみるときに

「ギガが減る」

という言い方をします。このギガとはなんなのでしょう? また、コンピューターを買うときに、メモリが8ギガバイトだとか、ハードディスクの容量が1テラバイトだとかいう言い方をします。このギガ、テラ、バイトが何を指すのか、正確に知っているでしょうか。

通信速度の理解

インターネット接続をするときに「ベストエフォート1Gbps」といった表現をみたことはないでしょうか。本書では「ベストエフォート」といった表現や「bps」等の通信速度に関する知識も合わせて学びます。

実践的データ量の感覚

さらに、データ量の土地勘をつけることを目標とします。スマートフォンで読んでいるライトノベルや、撮った写真が、どの程度の記憶容量を占めているのかを計算し、実際のファイルの大きさとも比べて、データ量に対する土地勘を養います。

1.1.2. USB: 端子の規格と通信の規格(第2章)

たくさんのUSBケーブルが溢れていて、どのケーブルを使ったらいいか迷ったことはないでしょうか。近年は USB-C ケーブルが主流になりつつありますが、実は同じ見た目の USB-C ケーブルも、ケーブルによっては通信ができなかったり、十分な通信速度がでなかったりします。

例えば以下のような経験はありませんか?

  • スマートフォンを充電できるUSB-Cケーブルが、ノートPCとモニターの接続に使えない

  • 外付けSSDを接続したが、想定よりも遅い転送速度になる

  • PD(Power Delivery)対応と書かれたケーブルと非対応のケーブルの違いがわからない

本書では、このような日常的な疑問の背景にある技術規格について理解を深めます。

1.1.3. コンピューター内部での数の表現(第3章)

2進法や16進法などの基数の考え方(この章の後半で復習します)をもとに、コンピューター内部でどのように数値が表現されるかを学びます。

整数は「2の補数表現」という方法で表されており、これによりコンピューターは負の数を扱うことができます。また、小数は「浮動小数点表現」で扱われますが、これは絶対的な精度ではなく相対的な精度で数を表現するため、計算によっては誤差が生じることがあります。

これらの表現方法には限界があり、表現できる数の範囲を超えると「桁あふれ(オーバーフロー)」が発生します。また、浮動小数点表現では表現できない数が多数あり、これが「表現誤差」の原因となります。こうした問題は、銀行のシステムや科学計算など、正確な数値計算が必要な場面で重要な課題となります。

1.1.4. コンピューター内部での文字の表現(第4章)

今、みなさんが読んでいるこの文書の文字はコンピューター内部では、数値で表現されています。Webページやメールを読むとき文字が意味のない文字や記号の羅列になってしまういわゆる「文字化け」という現象に悩まされたことはないでしょうか。これは、コンピューター内部で文字を扱う方法が一通りではないことに起因しています。

コンピューター内部での文字の表現方法はコンピューター開発のさまざまな歴史を抱え込んで発展してきたため、必ずしも一貫した規則があるわけではなく、あまり美しい部分ではありません。しかし、データを扱う際には必要な知識となります。

1.1.5. フォント(第5章)

画面や印刷物に表示される文字の形(字形)は、コンピューターの中では文字の番号とは別に、フォントのデータとして用意されています。同じ文字でも、明朝体とゴシック体では印象や読みやすさが変わります。書体の仕組みと、文書を作るときの書体の選び方を学びます。

1.1.6. 論理演算とブール代数(第6章)

今日のコンピューターは、スイッチのオンとオフに相当する0と1の信号を処理する部品で構成されています。本書では、どのようにして単純な0と1の演算からコンピューターが成り立っているのかを垣間見ることを目標とします。その基礎となるのが、0と1の2つの値だけを扱うブール代数です。 ブール代数では論理和(OR)演算を「+」で表すことがあり、この場合1+1=1となります。これは通常の算術演算とは異なる演算体系です。まずは、普段慣れ親しんだ四則演算から離れて、コンピューターの基礎である論理演算の理論となるブール代数について学びます。

1.1.7. 論理回路の設計と記憶の仕組み(第7章・第8章)

コンピューターはスイッチのオンとオフの組合せによって定義される論理演算によって、どのように計算をしているのか、簡単な論理回路の構成を通して学びます。また、論理回路を用いてコンピューター内でデータを記憶しておく仕組みを、記憶回路の基本となるフリップフロップ回路を通して学びます。

1.1.8. 情報理論(第9章)

情報理論は、1948年にクロード・シャノンによって創始された、情報の数学的な性質を研究する学問です。ビット単位での情報量の定量化、情報の圧縮、ノイズのある通信路での情報伝送などを数学的に扱います。この理論は現代のデジタル技術の基礎となっています。

情報理論と現代技術の関係

情報理論は現代技術の多くの分野に深い影響を与えています。例えば

  • 深層学習(ディープラーニング): 機械学習モデルのトレーニングでは、クロスエントロピーと呼ばれる情報理論に基づく損失関数が広く使われています

  • データ圧縮: 画像圧縮(JPEG)、音声圧縮(MP3)、動画圧縮(H.264/H.265)はすべて情報理論の原理に基づいています

  • 通信システム: 5G通信やWi-Fi、Bluetoothなどのワイヤレス通信技術は、シャノンの通信理論に基づいた符号化技術を使用しています

  • セキュリティ: シャノンは暗号の安全性も情報理論の立場から論じました(1949年)。ただし、現在広く使われている暗号の多くは、後で述べる計算量理論に安全性の根拠を置いています

どれも、私たちが日常的に使っている技術の中で働いています。

データ圧縮

シャノンが情報理論で扱ったもう1つの重要な対象がデータ圧縮です。大きなファイルを Windows 等で zip 形式で「圧縮」したことがある人もいるのではないでしょうか。データをできるだけ小さなサイズに「圧縮」することは、通信のコストを下げる上でも重要です。シャノンは、データを圧縮する方法について研究し、その理論的限界を示しました。普段扱っている音声や画像ファイルは、そのほとんどが圧縮されています。

たとえば、パソコンやスマートフォンで使えるGoogle日本語入力の辞書には、情報理論的な下限に近い大きさでデータを表しながら、そのまま検索もできるデータ構造(簡潔データ構造)が使われています。辞書は検索しなくてはならないので、圧縮したままでは不便と思われるかもしれません。実は、圧縮の仕方を工夫すると、元に戻さずに高速に検索できます。圧縮したデータがメモリに収まりやすくなるため、かえって速くなることもあります。本書では、データ圧縮の考え方についても学びます。

データ圧縮や誤り訂正符号を支える重要な考え方が情報量です。シャノンは、事象の起こりにくさを確率の対数ではかることで情報量を定量化し、確率分布のもつ不確実性を表す測度として情報エントロピーを定義しました(統計力学のエントロピーと同じ形の式で表されます)。定義と使い方は、情報理論の章でくわしく扱います。

誤り訂正符号

1977年に打ち上げられた宇宙探査機ボイジャー1号は、2026年9月の時点で地球から約257億km離れています。電波(光の速さ)でも片道24時間近くかかる距離で、2026年11月には地球から「1光日」(光が1日に進む距離、約259億km)に達します。voyager2012年に太陽風の届く範囲(太陽圏)を出て、現在は恒星間空間を秒速約17キロメートルの速さで飛行しています。

ボイジャー1号は、今も定期的に地球と通信を行っています。地球からボイジャーへは16bpsの速度で命令が送信され、ボイジャーからは今も約160bpsの通信速度で観測データを地球に送信しています。ボイジャーからの電波を地球で受信するまでに、ノイズによりデータが破壊されてしまうことがあります。デジタルデータではわずかなデータの破損も致命的になり得ます。

ノイズ対策としてボイジャー1号の通信には、畳み込み符号やリードソロモン符号といった誤り訂正符号技術が用いられています。一部のデータが破損しても、受信時に復元できる仕組みです。この技術はCD、携帯電話やWi-Fiの無線通信、二次元バーコードのQRコードにも用いられています。汚れでQRコードがある程度欠損していても、正しくデータを読み取ることができるように設計されています。

この誤り訂正符号技術のもとになる理論は、先ほど触れたシャノンの情報理論の成果です。シャノンが論文「通信の数学的理論」(1948)でこの理論を発表したことからもわかるように、情報理論は「効率的な通信を行うための数学理論」です。第9章では、細部には立ち入らずに、シャノンの誤り訂正符号の考え方がなぜ革新的であったのかを学びます。

オペレーティングシステム(OS)は、WindowsやmacOSなどのコンピューターの基本ソフトウェアで、ハードウェア資源の管理や利用者とのやりとりを受け持ちます。また、プログラミング言語で書かれたプログラムは、コンパイラやインタプリタによってコンピューターが実行できる形に変換されます。こうしたソフトウェア側の仕組みは、本書では章として取り上げません。

1.1.9. アルゴリズムと計算量(第10章)

アルゴリズムとは、問題を解くための手順や方法を指します。日常生活でも料理のレシピや組み立て説明書などの形でアルゴリズムを利用しています。コンピューター科学では、問題を解くための効率的なアルゴリズムの設計が重要な研究テーマとなっています。

アルゴリズムの効率は、実行に必要な時間(時間計算量)と使用するメモリ量(空間計算量)で評価します。特に問題のサイズが大きくなったときの計算量の増加率が重要であり、これをビッグO記法(O(n)、O(n2)など)で表現します。

本書では、基本的なアルゴリズムとその計算量について学びます。

1.1.10. 計算可能性と計算量理論(第11〜13章)

第11章では、まず、どれほど時間をかけてもコンピューターでは解けない問題があることを示します。その代表が、プログラムが止まるかどうかを判定する「停止性問題」です。

計算量理論はアルゴリズム理論をさらに抽象化し、問題そのものの本質的な難しさを研究する分野です。どんなアルゴリズムを使っても効率的に解けない問題が存在することや、効率的に解けるかどうかがまだ証明されていない問題が存在することを学びます。

コンピューター科学では、

「2地点間の最短経路を求めよ」

や

「全国に \(k\) 箇所ある営業所を重複せずに一巡する最短経路を求めよ」

といった問題が与えられたとき、その問題の「難しさ」について考える「計算量理論」という分野があります。計算の「難しさ」を語るには、まず、どのようなコンピューターで計算するのかを決めなくてはなりません。これを計算モデルといいます。本書では詳細な形式化は避けますが、具体的には決定性チューリングマシンに相当する計算モデルを想定します。これは一般的なコンピューターでの計算を抽象化したモデルです。

計算量理論でいう計算の「難しさ」は、問題の入力サイズが大きくなるに従って計算時間や途中の計算で必要となる記憶領域がどの程度必要になるかを基準にして定義されます。先ほどの巡回経路の問題では、巡らなくてはならない営業所の数 \(k\) を入力サイズとしたとき、営業所の数 \(k\) が大きくなると、巡回の順番の候補は \((k-1)!/2\) 通り(出発点を固定し、逆回りを同じとみなした場合)と爆発的に増えます(練習問題7)。候補をうまく絞り込む工夫により、数万か所規模の例が厳密に解かれたこともありますが、どんな入力に対しても、\(k\) が大きくなっても現実的な時間で厳密な最短経路を求められる方法は知られていません。

2つの有名な問題を見比べてみましょう。数独とルービックキューブです。 rubiks cube sudoku この2つの問題は、どちらが難しい問題だと思いますか? コンピューター科学の中でももっともコアな領域に属する計算量理論によれば、手順を1つ見つけるという意味では、数独の方がはるかに難しい問題であると信じられています。

数独であればマス目の数は 24, 34, 44,…​の順に大きくなります。このマス目を決定する \(n=2, 3, 4, \ldots\) を数独の問題の入力サイズとします。一方でルービックキューブのキューブの数は 23, 33, 43, …​ の順に大きくなります。この \(n=2, 3, 4, \ldots\) をルービックキューブの問題の入力サイズとします。

数独は問題の入力サイズが大きくなるに従って解くのに要する時間は、入力サイズに対して飛躍的に大きくなるため、大きなサイズの数独を厳密に高速に解くことができるアルゴリズムは知られていません。一方で、ルービックキューブは入力サイズが大きくなっても、数独ほどは入力サイズに対して大きな影響をうけずにすべての面の色を揃える手順を見つけるアルゴリズムが知られています。

ルービックキューブは数独と比べて簡単に解けると述べました。ここで「解ける」とは、面の色を揃えるたくさんの手順のうち1つが見つかるという意味です。見つかった手順が最短であるとは限りません。

実はルービックキューブを解くための最短の手順を求める問題は、とても難しいことが知られています。3×3×3の通常のルービックキューブはどんな出発点からでも、高々20回の手順(回転)を経ればすべての面を揃えられることが2010年にようやく証明されました(回転の数え方を、180度回転も1手と数えるハーフターンメトリックとした場合)(このような最短の手順数は God’s Number と呼ばれています)。

さらに、一般のサイズ \(n\)(キューブ数 \(n^3\)個)のルービックキューブを解く最短の手順を見つける問題はNP完全と呼ばれるとても難しいと考えられている問題(NPやPについては後の章で説明します)に属することが2018年にMITのコンピューター科学者 Erik Demaine らによって証明されました。

ところで、数独もルービックキューブも正解を与えられれば検算はとても簡単です。数独であれば、縦横と各区画に相異なる数字が過不足なく入っていることを確認するだけですし、ルービックキューブであれば、各面が同じ色であることを確認するだけです。

以上の内容をふまえて、コンピューター科学で最も有名な未解決問題の話をすることにします。それは、とてもいいかげんな表現を恐れずにいうと、以下のような問題です。

検算が簡単な問題は、解くのも簡単か?

この問題は「P≠NP予想」として知られており、1971年にスティーブン・クックにより定式化されて以来、だれも証明に成功していません。米国のクレイ数学研究所はこの問題を懸賞問題の1つとして、100万ドルの懸賞金をかけています。

本書では、ここでの怪しい説明よりはほんの少しマシな説明を通して、計算量理論の初等的な話題をいくつか取り扱い、コンピューター科学で扱う「計算」の概念について理解を深めます。

計算量理論の応用:現代暗号

現代の公開鍵暗号システムの多くは、特定の数学的問題の計算困難性(たとえば、大きな合成数の素因数分解や、離散対数問題など)に基づいて設計されています。これらの問題は、現在知られている最良のアルゴリズムでも、問題サイズが大きくなると現実的な時間での解決が困難であると考えられています。

現在実用的に用いられている暗号のほとんどは、理論上は時間をかければ解読できるけれども、それは何万年、何億年もかかるかもしれず現実的な時間では解読できないことに依拠して暗号の安全性を実現しています。計算の難しさに基づく暗号は、解けないのではなく、解くのにとてつもなく時間がかかることで安全性を担保しているのです。

難しい問題における問題のサイズと計算量について、とてもよくわかる動画があります。YouTubeで8分ほどの動画です。ぜひ視聴してください。

2. 前提知識: n進法の復習

ここから先を読み進める上で必須の知識です。忘れている人は、ここで復習しておいてください。基本的な数の変換は、コンピューター内部のデータ表現を理解する上で欠かせない基礎となります。章末の練習問題で、変換の手順を確かめられます。

2.1. 位取り記数法と基数

高校の「数学A」や「情報I」で習う数の2進法から10進法、10進法から2進法への変換の復習です。

現在のデジタルコンピューターはスイッチのオン・オフ、電圧の高・低といった2つの異なった状態に基づいて設計されています。そのため、コンピューター内部のデータはすべて、0と1のみを用いた数の表記法である2進法で表されます。2進法の1桁分のデータ量を1ビット、8ビット分を1バイトとよびます。これらデータ量の単位については第2章「コンピューター発展史とデータの単位」でくわしく扱いますので、ここではその前提となるn進法の復習をしておきます。

我々が普段つかっている10個の記号0から9を用いた数の表現を10進法といいます。用いる記号の数により、以下のような様々なn進法の数表現が考えられます。n進法のnを基数(radix or base)といいます。

表 2. 基数の異なる数の対応表
10進 2進 3進 4進 8進 16進

0

0

0

0

0

0

1

1

1

1

1

1

2

10

2

2

2

2

3

11

10

3

3

3

4

100

11

10

4

4

5

101

12

11

5

5

6

110

20

12

6

6

7

111

21

13

7

7

8

1000

22

20

10

8

9

1001

100

21

11

9

10

1010

101

22

12

A

11

1011

102

23

13

B

12

1100

110

30

14

C

13

1101

111

31

15

D

14

1110

112

32

16

E

15

1111

120

33

17

F

16

10000

121

100

20

10

16進法では、一桁の数を表すのに16種類の記号が必要となります。普段つかっている0から9の十種類の記号では、数がたりなくなるため0,…​,9,A,B,C,D,E,Fの16種類の記号を用いて数を表現します。

2進法の1010と10進法の1010は、表現は同じでも異なる数を表しています(図 1)。そのため、基数を数表現の右下に括弧で表して、n進法による数表現を区別します。ただし、n=10のときは基数の表記を省略します。

10進法の1010は各桁の重み1000,100,10,1で千十、2進法の1010は重み8,4,2,1で10
図 1. 同じ並びでも、基数が違えば桁の重みが違う

各桁の数字に、その桁の重み(基数のべき乗)を掛けて足し合わせたものが、表している数です。

  • 2進法の1010は、10進法の10と等しい。1010(2)=10

    • 1010(2) = 1×23 + 0×22 + 1×21 + 0×20 = 8 + 0 + 2 + 0 = 10

    • 一般にn桁のr進法の整数表現の各桁を \(a_{n-1}a_{n-2}\cdots a_0\) とおくと

\[\begin{align*} a_{n-1}a_{n-2}\cdots a_{0(r)} &=\sum_{i=0}^{n-1}a_ir^i\\ &= a_{n-1}r^{n-1}+a_{n-2}r^{n-2}+\cdots+a_0r^0 \end{align*}\]
  • 小数でも同様。小数点より右の桁の重みは \(r^{-1}, r^{-2}, \ldots\) となる。0.011(2) = 0.375

    • 0.011(2) = 0×2-1 + 1×2-2 + 1×2-3 = 0 + 0.25 + 0.125 = 0.375

    • 一般に小数点以下m桁のr進法の小数表現の各桁を \(a_{-1}a_{-2}\cdots a_{-m}\) とおくと

\[\begin{align*} 0.a_{-1}a_{-2}\cdots a_{-m(r)} &=\sum_{i=-m}^{-1}a_ir^i\\ &= a_{-1}r^{-1}+a_{-2}r^{-2}+\cdots+a_{-m}r^{-m} \end{align*}\]

2進法から10進法への変換は、この式のとおりに重みを足し合わせるだけです。

2.2. 10進法から2進法への変換

逆向きの変換は、整数部と小数部で手順が異なります(図 2)。

  • 整数部: 2で割り、余りを書きとめることを商が0になるまで繰り返します。余りを下から(最後に出たものから)順に並べると2進法の表現になります。

  • 小数部: 2倍し、整数部分(0か1)を取り出して残りの小数部分をまた2倍することを繰り返します。取り出した数字を上から(最初に出たものから)順に並べます。

13を2で割り続けると余りは1,0,1,1で下から読んで1101。0.625を2倍し続けると整数部分は1,0,1で上から読んで0.101
図 2. 10進法から2進法への変換の手順(13.625の例)

なぜこれでよいのかは、10進法で同じことをしてみるとわかります。10進法の数 12345 を 10 で割り続ければ、余りとして 5, 4, 3, 2, 1 が順に出てくるので、逆順に並べれば 12345 に戻ります。2で割ったときの余りは2進法の一番下の桁(\(2^0\) の位)で、商はその桁を取り除いた残りです。これを繰り返すと、下の桁から順に1桁ずつ取り出せます。小数部を2倍する操作は、小数点を1桁右へずらして \(2^{-1}\) の位を整数部分へ押し出す操作にあたります。

小数部の変換は、いつも終わるとは限りません。たとえば 0.1 は2進法では 0.000110011001…​(2) と、0011 がどこまでも繰り返す循環小数になります(練習問題6)。これは第3章で学ぶ浮動小数点数の誤差の原因の一つです。

2.3. 2進法と16進法の変換

24=16 であることから、2進法の4桁(4ビット)は、16進法の1桁にちょうど対応していますので、2進法の整数を16進法に変換するのは簡単です。2進法の数を下位桁から4桁ごとに区切って、4桁単位で16進法の表現に置き換えるだけです(図 3)。小数部分は小数点から右へ4桁ずつ区切り、足りない桁は右に0を補います。16進法から2進法へは、逆に各桁を4桁の2進法に置き換えます。

2進法から16進法への変換
\[\begin{align*} 011010_{(2)} = {00011010}_{(2)} = {\underbrace{0001}_{1} \underbrace{1010}_{A}}{}_{(2)} = 1A_{(16)} \end{align*}\]
2進法11010は上位に0を補って0001 1010と区切り1A。小数0.101は右に0を補って0.1010とし0.A
図 3. 2進法と16進法の変換: 小数点を基準に4桁ずつ区切る

同じ考え方で、23=8 なので2進法の3桁は8進法の1桁に対応します。

  • 00→01→11→10 のように隣接する数字の並びが1ビットしか異ならないように2進法の数字の順番を並べ替えた数の符号化をグレイコードと呼びます。回転角を読み取る装置(ロータリーエンコーダー)などで、読み取りの途中で大きく値が飛ぶ誤りを防ぐために使われます。

  • 3進法のバリエーションとして平衡3進法が知られています。平衡3進法は-1, 0, 1の3つの数字を使って基数3の数を表現する方法で、符号(正負)を別に持たなくても負の数を表せる利点があります。

変換の手順をもう少していねいに確認したい人は、補足資料 2進法の表記と変換 を参照してください。

3. 練習問題

問題1: 基数変換の基本

(1) 10100010(2) を10進法に変換せよ
(2) 10100010(2) を16進法に変換せよ
(3) 201 を2進法に変換せよ
(4) 201 を16進法に変換せよ
(5) 20A(16) を2進法に変換せよ
(6) 20A(16) を10進法に変換せよ
(7) 0.1111(2) を10進法に変換せよ

解答

(1) 162
10100010(2) = 1×27 + 0×26 + 1×25 + 0×24 + 0×23 + 0×22 + 1×21 + 0×20 = 128 + 32 + 2 = 162

(2) A2(16)
下位から4桁ずつ区切って 1010 0010(2)。1010(2)=10=A(16)、0010(2)=2 なので A2(16)。

(3) 11001001(2)
201 を商が 0 になるまで順に 2 で割り、余りを下から順に並べます(表 3)。検算: 128+64+8+1 = 201。

表 3. (3)の計算

余り

201 ÷ 2 = 100

1

100 ÷ 2 = 50

0

50 ÷ 2 = 25

0

25 ÷ 2 = 12

1

12 ÷ 2 = 6

0

6 ÷ 2 = 3

0

3 ÷ 2 = 1

1

1 ÷ 2 = 0

1

(4) C9(16)
(3)の結果を4桁ずつ区切ると 1100 1001(2) = C9(16)。16で割る方法でも、201 = 16×12 + 9 から C9(16) と求められます。

(5) 1000001010(2)
各桁を4桁の2進法に置き換えて 0010 0000 1010(2)。先頭の0を省くと 10 0000 1010(2) です。途中の0000を省かないように注意してください。

(6) 522
2×162 + 0×161 + 10×160 = 512 + 0 + 10 = 522。A を 10 と読み替えることを忘れないようにしましょう。

(7) 0.9375
0.1111(2) = 2-1+2-2+2-3+2-4 = 0.5+0.25+0.125+0.0625 = 0.9375。0.1111(2) に 0.0001(2) を足すと 1 になることから、1 − 2-4 と求めることもできます。

問題2: 2進法・10進法・16進法の相互変換

(1) 1101(2) を10進法と16進法に変換せよ
(2) 101011(2) と 1110010(2) を16進法に変換せよ
(3) 25 を2進法と16進法に変換せよ
(4) 3C(16) を2進法と10進法に変換せよ

解答

(1) 1101(2) = 1×23 + 1×22 + 0×21 + 1×20 = 13、16進法では D(16)。4桁の2進法はそのまま16進法の1桁になります。

(2) 101011(2) = 0010 1011(2) = 2B(16)、1110010(2) = 0111 0010(2) = 72(16)。区切りは必ず右(下位)から4桁ずつです。左から区切って 1110 010 とすると誤りになります。

(3) 25 ÷ 2 = 12 余り 1、12 ÷ 2 = 6 余り 0、6 ÷ 2 = 3 余り 0、3 ÷ 2 = 1 余り 1、1 ÷ 2 = 0 余り 1。余りを下から並べて 11001(2)。4桁ずつ区切ると 0001 1001(2) なので 19(16)。

(4) 3(16) = 0011(2)、C(16) = 1100(2) なので 0011 1100(2) = 111100(2)。10進法では 3×16 + 12 = 60。

問題3: 小数を含む変換

(1) 0.A(16) を10進法に変換せよ
(2) 13.625 を2進法と16進法に変換せよ
(3) 2F.A(16) を2進法に変換せよ
(4) 1110.101(2) を16進法に変換せよ

解答

(1) 0.A(16) = 10 × 16-1 = 10/16 = 0.625

(2) 整数部 13 = 1101(2)。小数部は 0.625×2 = 1.25 → 1、0.25×2 = 0.5 → 0、0.5×2 = 1.0 → 1 で .101(2)(図 2)。よって 1101.101(2)。16進法では、小数部を右に0を補って 0.1010(2) = 0.A(16) とし、D.A(16) です。(1)の結果 0.A(16) = 0.625 とも一致します。

(3) 2(16) = 0010(2)、F(16) = 1111(2)、A(16) = 1010(2) なので 0010 1111.1010(2)。前後の余分な0を省いて 101111.101(2)。

(4) 小数点を基準に、整数部は右から、小数部は左から4桁ずつ区切ります。1110.1010(2) となり、E.A(16)。小数部を 0101 と左に0を補うと値が変わってしまうので注意してください。

問題4: 桁数と表せる数の個数

(1) 8桁の2進法(8ビット)では、何通りの数を表せるか。0から始めて表せる最大の数を10進法と16進法で答えよ。
(2) 0から1000までの整数をすべて区別して表すには、2進法で最低何桁必要か。
(3) 16進法で4桁の数は、2進法では何桁に相当するか。16進法4桁で表せる最大の数を10進法で答えよ。

解答

(1) 各桁が0か1の2通りなので 28 = 256通り。0から数えるので最大は 256 − 1 = 255 = FF(16) です。「256」と答えてしまう誤りが多いので注意しましょう。

(2) 0から1000までは1001個の数です。29 = 512 < 1001 ≤ 210 = 1024 なので、10桁(10ビット)必要です。

(3) 16進法の1桁は2進法の4桁にあたるので 16桁。最大は FFFF(16) = 164 − 1 = 65535 です。

問題5: 8進法への変換

2進法の数 110101101(2) を8進法に変換せよ。また、3桁ずつ区切る方法でよい理由を説明せよ。

解答

右から3桁ずつ区切って 110 101 101(2)。各3桁は 110(2)=6、101(2)=5 なので 655(8) です。検算すると 6×64 + 5×8 + 5 = 429 で、110101101(2) = 256+128+32+8+4+1 = 429 と一致します。

理由: 23 = 8 なので、2進法の桁の重みを3桁ごとにまとめると 1, 8, 82, …​ となり、8進法の各桁の重みと一致します。3桁の2進法で表せるのは 0〜7 のちょうど8通りで、8進法の1桁の数字と1対1に対応します。

問題6: 0.1を2進法で表す

10進法の 0.1 を2進法で表すとどうなるか。小数第12位まで求め、どのような規則で数字が並ぶか答えよ。

解答

2倍して整数部分を取り出す操作を続けます。

計算 取り出す数字

0.1 × 2 = 0.2

0

0.2 × 2 = 0.4

0

0.4 × 2 = 0.8

0

0.8 × 2 = 1.6

1

0.6 × 2 = 1.2

1

0.2 × 2 = 0.4

0(2行目と同じ計算に戻った)

0.4 × 2 = 0.8

0

0.8 × 2 = 1.6

1

0.6 × 2 = 1.2

1

…

…

整数部分を上から並べると 0.000110011001…​(2) で、2桁目以降は「0011」が繰り返されます。小数部分が 0.2 に戻った時点から同じ計算が繰り返されるためで、いつまでも0にならない循環小数です。

コンピューターは有限の桁しか記憶できないので、0.1を2進法で正確に記憶することはできず、途中で丸めた近い値を使います。第3章の浮動小数点数で、この誤差がどのような結果を生むかを学びます。

問題7: 巡回経路の候補の数

営業所が \(k\) 箇所あり、どこか1か所から出発してすべての営業所を1回ずつ訪れて出発点に戻る経路を考える。出発点を固定し、同じ経路を逆回りにしたものは同じ経路とみなすと、候補は \((k-1)!/2\) 通りある。

(1) \(k=10\) と \(k=20\) のそれぞれについて、候補の数を求めよ。
(2) 1秒間に10億(109)通りの経路の長さを調べられるコンピューターで、すべての候補を調べるのにかかる時間を、\(k=10\), 20, 25 について見積もれ。

解答

(1) \(k=10\): 9!/2 = 362880/2 = 181,440通り。\(k=20\): 19!/2 ≈ 6.08×1016通り(約6京)。

(2) 候補の数を109で割ります。

  • \(k=10\): 181440 ÷ 109 ≈ 0.00018秒。一瞬です。

  • \(k=20\): 6.08×1016 ÷ 109 ≈ 6.08×107秒 ≈ 約1.9年。

  • \(k=25\): 24!/2 ≈ 3.10×1023 通りなので、3.10×1014秒 ≈ 約980万年。

営業所が10か所から20か所へ2倍になっただけで、かかる時間は 19!/9! ≈ 3.4×1011 倍(約3400億倍)になります。コンピューターが1000倍速くなっても、\(k=25\) では約1万年かかります。このように、すべての候補を調べる方法は入力が少し大きくなるだけで使えなくなります。第12章では、こうした問題の難しさを計算量理論の言葉で扱います。


以上です


← 目次へ戻る

© 久保山哲二 「コンピューター科学概論」講義資料 — CC BY-NC-SA 4.0 (表示 - 非営利 - 継承)で公開しています。