2023.03.31

その他

小学生でも分かる! コンピューターはどうやって計算しているのか【前編:2進数での情報の表し方】

※思ったり内容が長くなったので前編、後編に分けて投稿します。
前編である今回は「コンピューターが実際にどうやって計算しているのか」の前に、前提知識として「コンピューターが2進数を使用しているということ」「2進数での色んな情報の表し方」を書いていきます。
「コンピューターが実際にどうやって計算しているのか」は後編の中で書いていますのでそちらをご覧ください。

宮崎クリエイティブチームでは毎月メンバー回り持ちで勉強会を開いています。

エンジニアだけでなく、デザイナーの方や内容に興味のある他チームの方も見ることのできる勉強会なので自分が発表する際には非エンジニアの人にもわかってもらえるような内容を心がけております。

そんな心意気で今までいくつかの発表を行ってきたのですが、せっかくなのでブログのネタにもしちゃおうという魂胆であります。

コンピューターはどうやって計算しているのかなどと大層なタイトルにしてありますが、内容としましては深い部分まで追求するようなものではなく浅瀬をうっすらと掬う程度のものです。

ですが、コンピューターが計算する原理という部分については浅からず掬えていると思いますので「コンピューターはどうやって計算しているのか」なんて全くイメージがわかない! という方も読んでいただけると幸甚に存じます。

葉っぱ一号

「幸甚(こうじん)」と読むそうです。今知りました。

コンピューターは計算機

そもそもコンピューターは何をする機械なのでしょうか。

「インターネットが見れるもの」とか「エクセルとかパワポを使うためのもの」など色々と意見はありそうですが、それらたくさんの目的を実現させているのは「計算」です。

Yahooでニュースを読むのも、YouTubeで動画を見るのも、お絵かきソフトでイラストを描くのも、莫大な計算を繰り返し行うことで実現しているものです。

計算をすることで現在コンピューターが行えるの数多の仕事を可能にしているなんて想像しづらい! と思われるかもしれませんが、単純な動作を繰り返したり、組み合わせたりすることで複雑なことを成し遂げるというのは強いて言えば人間も同じだと言えるかもしれません。

人間は五感といわれるようにインプットに関しては5つ種類がありますが、アウトプットに関しては「筋肉を動かす」という1種類だけです。
声も筋肉を動かした結果、声帯で音が鳴っているだけですので人間が動かしているのは筋肉だけ。
ただ筋肉を少し動かすという単純な動作を組み合わせたり繰り返したりすることで、歩くことができ、話すことができ、様々なものを作ることができています。

そう考えると、複雑なものの根源は実はすべて単純なことのなのではないかという気さえしてきます。

まぁこれは過言かも知れませんが、コンピューターが計算を繰り返すことで様々なことを実現しているということは本当のことなのです。

それではコンピューターはどうやって計算しているのか、言い換えるならば、何を使って計算しているのか。

コンピューターを日本語訳すると「電子計算機」です。

これからも分かる通り、コンピューターは電気を使って計算する機械なのです。

そんなことわかっとるわい! という声が聞こえてきそうですが、でも、よくよく考えると、意味わからなくないですか?

電気を使って計算をする

これがもし

そろばんを使って計算をする

なら意味は分かります。

でも「電気を使って計算をする」。そんな方法僕たち人間は学んでいません。

だから「電気を使ってどうやって計算をする」のかピンとくる人はほとんどいないと思います。
でも歴史上の頭のいい人たちがまさしく「電気を使って計算をする」ということを実現する方法を発明してくれました。

まさしく発明なのですが、原理は小学生でも理解できるような簡単なものです。

コンピューターは2進数を使う

さっそく「電気を使って計算をする」ことを実現する方法を話していきたいのですが、前提としてコンピューターは2進数を扱うということを認識しておかなければなりません。

2進数とは何かということについては難しく考える必要はありません。

普段私たちが使っているのが「0 1 2 3 4 5 6 7 8 9」の10種類の数字を使った10進数。

もし使う数字が「0 1 2 3」の4種類だけなら4進数。

逆に「0 1 2 3 4 5 6 7 8 9 A B C D E F」のアルファベットまで入れて16種類なら16進数となります。

ですので2進数は?

「0 1」の2種類だけを使うということになります。

それだけです。ルールは変わりません。

「次を表す数字が無ければ位(くらい)をあげる」。それだけ守って使う数字が減ったり増えたりするだけです。

10進数では、0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 と数字が増えていきますが、9の次を表す数字はありませんから、位をあげて10とする。

10 → 11 → 12 → 13 → 14 → 15 → 16 → 17 → 18 → 19 とまた数字が増えていって、また9の次を表す数字がないので位の数字をあげて20とする。

20 → 21 → ・・・ → 88 → 89 と増えていって、

90 → 91 → 92 → 93 → 94 → 95 → 96 → 97 → 98 → 99 まであがってきたら、1の位の9の次がないので10の位の数字をあげたい。でも10の位の9も次がないのでさらに位をあげて100とする。

こういう数字の表し方を「位取り記数法」といいます。

4進数の場合は、

0 → 1 → 2 → 3 と増えて、次がないので位をあげて10。(ただしこの10は10進数でいうところの4と同じ数です。)

10 → 11 → 12 → 13 と増えて、位をあげて20。(この20は10進数でいうところの8と同じ数です。)

20 → 21 → 22 → 23 → 30 → 31 → 32 → 33 まで増えたら、さらに位をあげて100となります。

2進数は0と1だけしか使わないので一見ややこしく見えるかもしれませんが同じように考えれば、

0 → 1 と数字が増えて、1の次を表す数字がないので位をあげて10。

10 → 11 とまた数字が増えて、またすぐに一番右の1の次がなくなったから、右から二番目の数字をあげたい。でも二番目の数字ももう次がないから位をあげて100となる。

続きも書いてみると、

100 → 101 → 110 → 111 → 1000 → 1001 → 1010 → 1011 → 1100 → 1101 → 1110 → 1111 → 10000 となるわけです。

2進数と10進数の対応表を書いてみるとこんな感じ👇

2進数 0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000
10進数 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

進数の変換

ぱっと見よくわからない2進数をどうやって数えるかという部分も10進数のときとルールは変わりません。

例えば「2597」という10進数の数字を読むとき、「にせんごひゃくきゅうじゅうなな」と読みますが、この読み方にルールが隠れています。

これは、「2 5 9 7」すなわち、「2個の千」と「5個の百」と「9個の十」と「7個の一」ということです。

式にすれば ( 2 × 1000 ) + ( 5 × 100 ) + ( 9 × 10 ) + ( 7 ) 

この千、百、十、一のことは位(くらい)と小学校の時に習いました。1の位、10の位、100の位というあれですね。

この位ですが、1の位、10の位、100の位・・・と書くより次の表記のほうが本質を表しています。

10⁰の位、10¹の位、10²の位・・・

この累乗されていく10は10進数の10です。指数部分がひとつ上がるにつれ位もひとつあがっていきます。

なので2進数では「2⁰の位」「の位」「の位」・・・というように位があがっていくのです。

一般化してn進数では「n⁰の位」「の位」「の位」・・・です。

もし4進数で「312」という数字があれば「4²の位」が3つ、「4¹の位」が1つ、「4⁰の位」が2つ、即ち

  ( 3 × 4² ) + ( 1 × 4¹ ) + ( 2 × 4⁰ )
⇔ ( 3 × 16 ) + ( 1 × 4 ) + ( 2 × 1 )
⇔ 48 + 4 + 2
= 54

このように10進数では54だということが分かります。

2進数で「1011」という数字があれば「2³の位」が1個、「2²の位」が0個、「2¹の位」が1個、「2⁰の位」が1個、即ち

  ( 1 × 2³ ) + ( 0 × 2² ) + ( 1 × 2¹ ) + ( 1 × 2⁰ )
⇔ ( 1 × 8 ) + ( 0 × 4 ) + ( 1 × 2 ) + ( 1 × 1 )
⇔ 8 + 0 + 2 + 1
= 11

10進数では11ということです。

逆に10進数を2進数にするにはどうすれば良いでしょうか?

例えば61という10進数の数字があったなら、2⁶(=64)よりは小さいけど2⁵(=32)よりは大きいので2⁵(=32)を61から取り出してあげて残り29。
【2⁵が1個 と 29 】

29は2⁴(=16)より大きいので29から2⁴(=16)を取り出してあげて残り13。
【2⁵が1個 と 2⁴が1個 と 13 】

13は2³(=8)より大きいので13から2³(=8)を取り出してあげて残り5。
【2⁵が1個 と 2⁴が1個 と 2³が1個 と 5 】

5は2²(=4)より大きいので5から2³2²(=4)を取り出してあげて残り1。
【2⁵が1個 と 2⁴が1個 と 2³が1個 と 2²が1個 と 1 】

1は2¹(=2)より小さいので2¹は取り出せない。
【2⁵が1個 と 2⁴が1個 と 2³が1個 と 2²が1個 と 2¹が0個 と 1 】

1は2⁰(=1)と同じなので取り出して、
【2⁵が1個 と 2⁴が1個 と 2³が1個 と 2²が1個 と 2¹が0個 と 2⁰が1個 】

よって10進数の61は2進数で表すと、「111101」ということになります。

もっと簡単に変換する方法はありますが、とにかく10進数から2進数への変換もできるということが分かってもらえたら大丈夫です。

さらに言えば、このように考えれば10進数2進数に限らず、何かしらの進数から別の進数への変換も可能だということが分かります。

余談:位取り記数法以外の記数法

普段はここまで考えずになんともなしに使っているこの位取り記数法ですが、実はこれも大変な発明です。数の数え方というのは歴史上様々なものがあり、古代エジプトでは

エジプト数字 𓏺 𓎆 𓍢 𓆼 𓂭 𓆐 𓁨
10進数 1 10 100 1000 10000 100000 1000000

このように数を表していたようです。

𓎆は馬のかかとが由来で、𓍢はぐるぐるに巻いたロープ、𓆼は睡蓮の花で、𓂭は指、𓆐は蛙になりかけのオタマジャクシで、ナイル川にたくさんオタマジャクシがいたから100000を表す数字になったそう。𓁨は天空を支えるヘフ神という神様らしいです。

この数字たちはとても面白いですが実際使うとなるとどうでしょう。

もし「34256」という数字を表したかったら、

𓂯𓆿𓍣𓎊𓏿

となります。

大変ですね。位取り記数法がいかに便利か実感できます。

余談ですが、𓏺𓎆𓍢𓆼𓂭𓆐𓁨これらの象形文字、ユニコードに収録されていました。ヒエログリフさえユニコードには入っているようです。すごいですね。

葉っぱ一号

個人的に
𓁲
コイツの存在がとても気になります。

なぜコンピューターは2進数を使うのか

進数の説明はここまでとして、コンピューターはどうして私たちが馴染みのある10進数ではなくて、ぱっと見よく分からない2進数なんてものを使っているのでしょうか?

それはコンピューターにとって2進数の方が扱いやすいからです。

コンピューターは電気を使って計算をすると前述しましたが、電気というのは単なる物理現象である以上思い通りにハンドリングできるものではありません。

電線の中を通っていくうちに減衰していったり、外部からの影響を受けてノイズが入ってしまったりするわけです。

例えば電気の流れる量で数値を表そうと思ったとき、9の強さで電気を送ったとしても届いた先では減衰して7の強さになってしまっているかもしれません。逆に5の強さの電流を受け取ったとして、それがもともといくつの強さだったのかを確信をもって答えることができません。それでは困るので、2進数という「0と1の二つの数字」すなわち、「二つの状態」のみで考えることによって、「電気が流れているか」「流れていないか」というシンプルな区別にすることができるのです。

電流が流れていたら1、流れていなかったら0。電圧がかかっていれば1、かかっていなければ0。このように二つの状態に絞ることで誤りの防止にもなるわけですね。

「表現しやすく、区別しやすい」という点において2進数は電気を使うコンピューターと相性がよく、翻ってこれがコンピューターが2進数を使う理由という訳でした。

『文字』も『色』も『画像』も『動画』も『音』も、2進数で扱える

コンピューターは2進数を使うと言われても普段コンピューターを使っているときに2進数を実感する機会はほぼないと思います。

コンピューターにとっては扱いやすい2進数であっても人間にとってはやっぱりなんだか暗号のようにみえる……。

なのでコンピューターは最終的には2進数で計算するのであっても我々の見えるところでは人間にとってわかりやすい形に変形してくれています。

というかそうしないと人間がうまくコンピューターを使えないのでわかりやすく変形するように設計されています。

2進数の入力なんてやってられませんよね。でも昔は似たようなことをやってたんだそうです。使いやすいように進化していった結果、ユーザーが直接2進数をいじる機会はなくなっていったということですね。

文字

先ほど、何かしらの進数は別の何かしらの進数に変換できるという話をしましたので、2進数で広く数字は表せるということは分かりました。

では「文字」はどうでしょう?

今、持っている武器は「数字」のみです。

その唯一の武器を使って文字を扱うにはどうしたらよいでしょう。

そう、文字に番号を振り分けてしまうのです。これを文字コードといいます。

文字コードには色々な種類がありますが、一番始めに使われたのは皆さんも聞いたことあるかもしれません。「American Standard Code for Information Interchange」の頭文字をとってASCII(アスキー)というコードです。

10進 16進 ASCII 10進 16進 ASCII 10進 16進 ASCII 10進 16進 ASCII
0 0 NULL 32 20 SP 64 40 @ 96 60 `
1 1 SOH 33 21 ! 65 41 A 97 61 a
2 2 STX 34 22 66 42 B 98 62 b
3 3 ETX 35 23 # 67 43 C 99 63 c
4 4 EOT 36 24 $ 68 44 D 100 64 d
5 5 ENG 37 25 % 69 45 E 101 65 e
6 6 ACK 38 26 & 70 46 F 102 66 f
7 7 BEL 39 27 71 47 G 103 67 g
8 8 BS 40 28 ( 72 48 H 104 68 h
9 9 HT 41 29 ) 73 49 I 105 69 i
10 A LF 42 2A * 74 4A J 106 6A j
11 B VT 43 2B + 75 4B K 107 6B k
12 C FF 44 2C , 76 4C L 108 6C l
13 D CR 45 2D 77 4D M 109 6D m
14 E SO 46 2E . 78 4E N 110 6E n
15 F SI 47 2F / 79 4F O 111 6F o
16 10 DLE 48 30 0 80 50 P 112 70 p
17 11 DC1 49 31 1 81 51 Q 113 71 q
18 12 DC2 50 32 2 82 52 R 114 72 r
19 13 DC3 51 33 3 83 53 S 115 73 s
20 14 DC4 52 34 4 84 54 T 116 74 t
21 15 NAK 53 35 5 85 55 U 117 75 u
22 16 SYN 54 36 6 86 56 V 118 76 v
23 17 ETB 55 37 7 87 57 W 119 77 w
24 18 CAN 56 38 8 88 58 X 120 78 x
25 19 EM 57 39 9 89 59 Y 121 79 y
26 1A SUB 58 3A : 90 5A Z 122 7A z
27 1B ESC 59 3B ; 91 5B [ 123 7B {
28 1C FS 60 3C < 92 5C \ 124 7C |
29 1D GS 61 3D = 93 5D ] 125 7D }
30 1E RS 62 3E > 94 5E ^ 126 7E ~
31 1F US 63 3F ? 95 5F _ 127 7F DEL

このように文字に番号を割り振って数字と文字を変換しているわけです。

文字をやり取りする場合、まずお互いに「これからASCIIコードで文字を送るよー」という合図を出し合って送る側は文字を数字にして送信し、受け取る側は数字を文字に戻して画面に表示する、という感じの流れになります。

例えば16進数で「48 65 6c 6c 6f 21」は文字に変換すると「Hello!」となります。
2進数だと「01001000 01100101 01101100 01101100 01101111 00100001」です。

ただ先ほども書いたように文字コードには色々と種類があります。

ASCIIコードはアメリカで最初期に作られたものなので割り当てられた文字はアルファベットや記号や数字や制御文字(装置に対して特別な動作をさせるための文字)だけ。

なので日本語を表すにはまた別の文字コード「JIS」「シフトJIS」「日本語EUC」「ユニコード」なんかが作られました。

もちろん文字コードによって文字に割り当てられた数字は違うので、送り手と受け手の文字コードに違いがあればうまく文字変換することができずに文字化けが発生してしまうのです。

逆に言うと文字化けが出てきた時には相手の文字コードと自分の文字コードを確認して合わせれば良いということですね。

さて、数字を使うことで「文字」を扱えることが分かりました。

次は、

色はどう表せばよいでしょうか。

今持っている武器は「数字」と「文字」ですが、文字で色を表すのは詩人にまかせましょう。

やはり色も数字で表します。

文字コードと同じように色の数字での表し方もいくつかの方法があります。

光の3原色を使うRBG

最もポピュラーな表し方。ディスプレイは光でいろんなものを表示するので相性がいいです。
Red:赤・Green:緑・Blue:青 それぞれの強さを数値で指定することで色を表現します。
webの世界ではそれぞれの強さを主に0~255の256段階に分けて表すことが多いです。
赤、緑、青がそれぞれ256段階に分かれるということは表現できる色の数は 256×256×256=16,777,216色にも及びます。
16,777,216色、これをフルカラーなんて言ったりします。
もちろん256段階より少なくしたり、多くしたりすることもできます。

色の3原色を使うCMYK

cyan:シアン・magenta:マゼンタ・yellow:イエロー・Key plate:黒 それぞれの強さを数値で指定することで色を表現します。

直感的に分かりやすいHSV・HSB

Hue:色相・Saturation:彩度・Value:明度 で表されます。
色相で何色かを決定し、彩度で鮮やかさを決定し、明度で明るさを決定します。
Vの代わりに、B(Brightness)を用いて、HSBとも言われます。

似てるけどちょっと違うHSL

Hue:色相・Saturation:彩度・Lightness/Luminance:輝度 で表されます。

HSB/HSVが明度を扱うのに対してHSLは輝度を扱います。輝度は「人間の目の特性を考慮」したものとのことです。
例えば原色の赤・緑・青を比べた時、人間の目では感覚的に緑が一番明るく、青が一番暗く見える。みたいなことも考慮されている計算方法を用いているようです。

画像

色が表現できるのなら画像も表現できそうな気がします。

と言うのも、PCに表示される画像というのは細かいドットの集合でしかないからです。

とても綺麗に見える写真でもPC上で拡大していけば四角いドットの集まりだということが分かります。

ただ色を順番に並べていっているだけなので、画像の左上から1つ1つのドットの色を指定していけば、全体を見たときに画像として認識されるものを表現できます。

仕組みとしては単純ですが、例えばフルHDの画像の場合、横1920ドット、縦1080ドットの計2,073,600ものドットが存在します。

しかもその一粒一粒に仮にRGB形式でフルカラーの色の情報を与えるとなると、めちゃくちゃ単純計算で2,073,600×24=49,766,400もの2進数が必要になります。ほぼ5千万です。(256段階を表せる2進数の数は8桁で、Red、Green、Blue3つ合わせて24桁必要なため)

文字の表し方で見たアスキー文字コードの「Hello!」なんて2進数で「01001000 01100101 01101100 01101100 01101111 00100001」だから48個の2進数で表現できたのに、画像一枚表現するにはほぼ5千万個もの2進数が必要だということです。

この情報量をどうにかして少なくしようと色々な圧縮方法というのが考えられているのでそのまんま5千万個の2進数が必要という訳ではないのですが、それでも画像を表すには文字を表すより莫大な情報が必要だということが分かります。

余談:ベクター画像について

↑で話した内容は、画像は画像でもラスター画像という種類のものについての話です。

ラスター画像の他にもベクター画像というものがありまして、こちらはまたちょっと話が変わってきます。

ベクター画像は、コンピュータグラフィックスなどにおいて、
画像を円や直線などのような解析幾何学的な
「図形」の集まりとして表現する表現形式である。

wikipedia先生はこう言いますがいまいちイメージつきにくいかと思います。

ベクター画像の中身は数式等で構成されていて、その数式を読み取ったブラウザ等のソフトが数式を元に画面に描画することでユーザーに見せる仕組みです。

なのでいくら拡大してもラスター画像のように粗が出てくることはなく、ファイルサイズも軽量なことが特徴です。

ただ数式で構成する関係上、エッジのはっきりしているイラストなんかはうまく表現できますが、写真などには向いていません。

写真を無理に図形の数式で表そうとするのはめちゃくちゃ高い演算能力が必要ですし、もし数式化できたとしても複雑な数式になりすぎてラスター画像よりファイルサイズが大きくなったりする可能性が高いです。

と、一旦説明してみましたがやはりいまいちイメージつきづらいと思うので実際の中身を見てみましょう。

ベクター画像には色々な種類がありますが、代表的なSVG(Scalable Vector Graphics)の中を覗いてみます。

<?xml version="1.0" encoding="UTF-8"?>
<svg id="donut" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  <defs>
    <style>
      .cls-1 {
        fill: #f7931e;
      }

      .cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-8 {
        stroke: #603813;
        stroke-miterlimit: 10;
        stroke-width: 20px;
      }

      .cls-2 {
        fill: #c355ff;
      }

      .cls-3 {
        fill: #754c24;
      }

      .cls-9, .cls-7 {
        fill: #ffc9d7;
      }

      .cls-4 {
        fill: lime;
      }

      .cls-5 {
        fill: #ffe21f;
      }

      .cls-6 {
        fill: #ff7478;
      }

      .cls-10 {
        fill: #fbb03b;
      }

      .cls-8 {
        fill: #e95500;
      }
    </style>
  </defs>
  <rect id="bg" class="cls-9" width="1000" height="1000"/>
  <circle id="circleDonut" class="cls-1" cx="500" cy="500" r="451.25"/>
  <path id="choco" class="cls-3" d="m612.81,493.55c0,16.12-53.18,111.2-127.32,124.09-71.36,12.41-167.84,80.41-149.88,191.78,16.12,99.92,100.48,141.82,164.38,141.82,249.22,0,451.25-202.03,451.25-451.25,0-51.57-67.69-145.04-180.5-145.04-77.63,0-157.94,88.46-157.94,138.6Z"/>
  <circle id="hole" class="cls-7" cx="500" cy="500" r="128.93"/>
  <rect id="rectGreen" class="cls-4" x="740.13" y="421.03" width="35.46" height="138.6" transform="translate(346.7 -313.24) rotate(30)"/>
  <rect id="rectRed" class="cls-8" x="417.81" y="778.81" width="141.82" height="41.9" transform="translate(-238.58 208.57) rotate(-19.47)"/>
  <rect id="rectYellow" class="cls-5" x="720.79" y="630.54" width="41.9" height="128.93" transform="translate(-273.95 655.33) rotate(-40.9)"/>
  <circle id="circlePink" class="cls-6" cx="844.88" cy="590.25" r="30.62"/>
  <circle id="circleOrange" class="cls-1" cx="580.58" cy="661.16" r="30.62"/>
  <circle id="circlePurple" class="cls-2" cx="628.93" cy="841.66" r="30.62"/>
  <g id="reflection01">
    <path class="cls-10" d="m151.62,479.92c5.91-41.14,16.15-81.63,32.26-120l-3.53,8.36c12.18-28.64,27.57-55.75,46.54-80.44l-5.47,7.08c15.96-20.55,34.21-39.18,54.75-55.17l-7.08,5.47c7.72-5.94,15.72-11.48,24-16.62,15.55-9.64,22.98-31.72,12.56-47.89s-31.24-22.87-47.89-12.56c-79.07,48.99-131.27,130.15-157.46,218.14-7.31,24.55-12.54,49.66-16.18,75-1.39,9.71-1.64,18.14,3.53,26.97,4.25,7.26,12.57,14.18,20.92,16.08,8.96,2.04,19.02,1.6,26.97-3.53,7.1-4.58,14.83-12.15,16.08-20.92h0Z"/>
  </g>
  <g id="reflection02">
    <path class="cls-10" d="m349.33,179.38c18.31,0,35.85-16.1,35-35s-15.38-35-35-35c-18.31,0-35.85,16.1-35,35s15.38,35,35,35h0Z"/>
  </g>
</svg>

48行目~63行目にかけて図形の数式が記述されています。
4行目~46行目まではその図形達に関するスタイルを宣言している部分です。

48行目に注目してみましょう。

<rect id="bg" class="cls-9" width="1000" height="1000"/>

rect(rectangle)即ち長方形を書いている部分です。

width="1000" height="1000"

の記述から分かる通り幅1000、高さ1000の長方形を表しており、23行~の

.cls-9, .cls-7 {
    fill: #ffc9d7;
}

によってピンク色 で塗りつぶしされていることが分かります。

もうひとつだけ見てみましょう。

49行目、

<circle id="circleDonut" class="cls-1" cx="500" cy="500" r="451.25"/>

これはx座標500、y座標500を中心とした半径451.25の円を表していて、

      .cls-1 {
        fill: #f7931e;
      }
      .cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-8 {
        stroke: #603813;
        stroke-miterlimit: 10;
        stroke-width: 20px;
      }

によって、オレンジ色 で塗りつぶされており、幅20pxで茶色 の線が付いていることが示されています。

ここまで見てきたrectとcircleだけを描写すると👇のような見た目です。

ここにさらに別の円や四角、パス図形なんかが加わって、最終的には👇のドーナツができあがるわけです。

動画

さぁ、動画です。

動画はどう表現すればいいでしょう?

今持っている武器は「数字」「文字」「色」「画像」です。

もちろん今回使う武器は「画像」ですね。

そもそも動画とはなんなのかというと、画像を連続で表示しているものです。

パラパラ漫画と同じです。

ですので画像を表現できるようになった今、動画はそれを連続で次々と切り替えていけば良いだけということになります。

どのくらいの頻度で切り替えていくかを表すのがfps(frames per second:フレームレート)と呼ばれるものです。

30fpsなら1秒間に30枚の画像を切替えます。ちなみに日本のテレビ放送はこの30fpsです。

画像のセクションで書いたように文字に比べて画像は莫大な情報量が必要でした。

その画像を1秒間に何十枚も表示させる動画はさらにさらに莫大な情報量が必要となります。

動画にも前の画像から変更のない部分の情報を削るなどのサイズ圧縮方法がありますが、それでも動画がめちゃくちゃ重いコンテンツであることは皆さんご周知のとおりですね。

簡単ですが動画の説明はこれまでにして、最後に音です。

音を表現するにも、そもそも音がどんなものかを考える必要があります。

音は波です。身近な例で言えば空気の振動です。

音の波にはそれぞれ形があり、大きさがあります。

その形状を保存できれば保存した形状を元にスピーカーが音を鳴らしてくれます。

それじゃあどうやって波の形状をデジタルデータとして記憶すればよいでしょうか。

音の波という連続的なもの(アナログ)を離散的なもの(デジタル)に変換するためにはたくさん分解するという方法をとります。

分解数が少なければあまり元々のアナログ情報に似てないデジタル情報ができあがるし、分解数がより多くすれば元々のアナログ情報にどんどん近づいていくことになります。

無限回分解すればアナログと同等のデジタル情報ができるでしょうが、分解数が多くなればなるほど情報量も増えていくのでバランスが大切ですね。

少し具体的に分解のイメージを見ていきましょう。

例えばこんな波があったとして👇

まずは、👇のようなイメージで時間あたりの分解数を決めます。

そしてその分解線と波との接点をプロットします。

ちなみにそのプロットした点を標本(サンプリング)、どれくらい分解するのかをサンプリング周波数といいます。

デジタル音楽を利用する方なら音楽データに「44.1kHz」という表記を見たことがあるかもしれません。これがサンプリング周波数になります。(単位はヘルツです)

44.1kHzということは1秒間に44,100回の分解を行っているということです。ハイレゾ音源なんかだと96~192kHzなので96,000~192,000回の分解になります。

さて、これで波という連続した曲線からいくつかの点をとりだすことができました。

この時間あたりに分解して標本を取り出す作業をまとめて標本化(サンプリング)といいます。

サンプリングによって横軸に関してはアナログ(連続的)からデジタル(離散的)に変換したということですね。

縦方向に分解したので次は横方向に分解です。

サンプリングした点をこの横線の間隔で一番近いものに当てはめていきます。

これで縦軸に関してもアナログからデジタルへの変換ができました。

この作業のことは量子化といい、何段階で分解するのかの数のことを量子化ビット数といいます。

音楽データでは普通の音源で16Bit、ハイレゾ音源だと24Bitというのが一般的です。16Bitは2の16乗(=65,536)段階、24Bitは2の24乗(=16,777,216)段階というめちゃくちゃ細かいレベルに分解されています。

最後にサンプリングと量子化によって得た値を2進数に変換する符号化という手順を行って音のデジタル化は完了になります。

前編まとめ

前編ではコンピューターが2進数を扱うということと、2進数での色んなデータの表し方を見てきました。

本来ならここからコンピューターがどうやって2進数の計算をしているのかを説明する予定でしたが長くなったので後編に分けます。

小学生のころに理科で習った方法がコンピュータの2進数の計算にそのまま使えるというとても楽しい内容になっているので興味を持っていただけたら是非続きも読んでみてください。

後編はこちら

この記事を気に入ったら

葉っぱ一号

葉っぱ一号

おいしいお店を探すのが好きです。おいしいお店のために遠出もしちゃいます。遠出したい衝動のためにおいしいお店を探すのかもしれません。そんなものですよね。

この人が書いた記事を見る >>