[logo] Web連載「数学ガールの秘密ノート」
Share

第457回 シーズン46 エピソード7
生成AIと学ぶ:場を作るAI(前編)

$ \newcommand{\TEXT}[1]{\textbf{#1}} \newcommand{\REMTEXT}[1]{\textbf{#1}} \newcommand{\LEQ}{\leqq} \newcommand{\GEQ}{\geqq} \newcommand{\PS}[1]{\left(#1\right)} \newcommand{\BRAC}[1]{\left[#1\right]}% \newcommand{\NOTOKI}{\quad\text{のとき}\quad}% \newcommand{\BINREP}[1]{{#1}_{(2)}} \newcommand{\DECREP}[1]{{#1}_{(10)}} \definecolor{CUD-GREEN}{rgb}{0.012,0.686,0.478}% 3,175,122 \definecolor{CUD-GOLD}{rgb}{0.890,0.690,0.000} % RGB(227,176,0) \newcommand{\GEQ}{\geqq} \newcommand{\LEQ}{\leqq} \newcommand{\NEQ}{\neq} \newcommand{\FOCUS}[1]{\fbox{ $#1$ }} \newcommand{\REDFOCUS}[1]{\textcolor{red}{#1}} \newcommand{\GREENFOCUS}[1]{\textcolor{CUD-GREEN}{#1}} \newcommand{\BLUEFOCUS}[1]{\textcolor{blue}{#1}} \newcommand{\BROWNFOCUS}[1]{\textcolor{brown}{#1}} $

登場人物紹介

:数学が好きな高校生。

テトラちゃんの後輩。 好奇心旺盛で根気強い《元気少女》。言葉が大好き。

リサ:自在にプログラミングを行う無口な高校生。コンピュータを自在に操る赤い髪の《プログラミング少女》。

図書室にて

ある日の放課後。

はいつものように図書室に行く。

すると、二人の少女、 テトラちゃんリサが並んで座っているのが見えた。

「テトラちゃん——」

テトラ「しー!」

テトラちゃんは唇に人差し指をあてて、(静かにして)のポーズ。

横にいるリサを見ると、腕組みをして座ったまま目を閉じている。

考えごとをしているようにも見えるけど、もしかして……

「リサちゃん、眠ってる?」

テトラ「そうです。だからお静かに」

テトラちゃんは小声でそう言った。

リサの前、そしてテトラちゃんの前にはそれぞれコンピュータが置かれている。

も小声になって尋ねる。

「二人でプログラミングをしてたのかな?」

テトラ「はい、そうです。 といってもリサちゃんは何か大きなシステムを作っているらしいです。 あたしはあたしで、 プログラミングの勉強をしていました」

「なるほど」

は改めて、 真っ赤な髪をして真っ赤なコンピュータを使う少女、リサを見る。

彼女は無口だけれど、プログラミングに長けている。

といっても眠りながら作ることはできないだろう……何か大きなシステムを作っている?

テトラちゃんのクイズ

テトラ「ところで先輩。クイズを一つ出したいと思いますっ! このプログラムを動かすと、何が表示されるでしょうか」

テトラちゃんはそういってコンピュータをに向けた。

クイズ:何が表示されるか?

「QUIZという手続きが定義されていて……

  • A2で、 $x$ に $0.1$ という値を代入する。
  • A3は、ループの始めで、繰り返しを継続する条件は $x \neq 1.0$ になっている。これを満たすならA4に進み、満たさないならA7にジャンプする。
  • A4は、ループの中身で、 $x$ の値を表示している。
  • A5は、ループの中身で、変数 $x$ の値に $0.1$ を加えている。
  • A6は、ループの終わりで、ここに来たらループの始めであるA3に戻る。
  • A7は、 $x$ の値を表示している。
  • A8は、手続きの終わり。
……ということだね」

テトラ「はい。その通りです」

「うん、これはわかる。簡単だよ。

  • A2を処理したら、 $x = 0.1$ になっている。
  • A3の条件 $x \neq 1.0$ は満たされているからA4に進む。
  • A4では、 $x$ の値として $0.1$ を表示する。
  • A5では、 $x$ の値に $0.1$ を加えるから、 $x = 0.2$ になる。
  • A6がループの終わりなので、A3に戻る……
うん、だから結局、 $x$ の値はA4を通るたびに $0.1$ ずつ増えた値が表示される。 でも $x = 1.0$ になってA3にくると $x \neq 1.0$ の条件は満たされなくなるので、A7にジャンプする。 A7で $x$ の値として $1.0$ が表示されるね」

「僕」の解答 $$ \begin{align*} &0.1\\ &0.2\\ &0.3\\ &0.4\\ &0.5\\ &0.6\\ &0.7\\ &0.8\\ &0.9\\ &1.0 \end{align*} $$

テトラちゃんは、の解答を見て、 大きな目をいたずらっぽく光らせた。 彼女にしては珍しい表情だ。

テトラ「先輩、やっぱりそう思っちゃいますよね?」

「えっ、違うの? $0.9$ までしか表示されないってこと? それは違うよ。 だって、A3の条件は $$ x \neq 1.0 $$ なんだよ。

  • もしも $x \neq 1.0$ なら、A4に進む。
  • もしも $x = 1.0$ なら、A7に進んで $x$ の値を表示して終了する。
この二つに一つなんだから、最後に表示されるのは絶対に $1.0$ だよね」

テトラ「はい。そう考えるのはもっともなんですが……」

「わからない……」

テトラ「実際に動かした結果はこちらになります」

テトラの解答

$$ \begin{align*} &0.1\\ &0.2\\ &0.30000000000000004\\ &0.4\\ &0.5\\ &0.6\\ &0.7\\ &0.7999999999999999\\ &0.8999999999999999\\ &0.9999999999999999\\ &1.0999999999999999\\ &1.2\\ &1.3\\ &1.4000000000000001\\ &1.5000000000000002\\ &1.6000000000000003\\ &1.7000000000000004\\ &1.8000000000000005\\ &1.9000000000000006\\ &2.0000000000000004\\ &\vdots \end{align*} $$

※注意:この結果はプログラミング言語に依存します。

「え?」

テトラ「実はこのプログラムは終わりません。表示は永遠に続きます。 なぜなら、A3からA6の繰り返しは無限ループになるからです」

「A3→A4→A5→A6→A3→A4→A5→A6→……をずっと繰り返すということ?」

テトラ「その通りです。A7には絶対にたどり着きません。 このクイズのポイントは浮動小数点数ふどうしょうすうてんすうにあります。 コンピュータでは $0.1$ のような数は、 浮動小数点数として扱われることがよくあります。 でも、浮動小数点数を扱うときにはとても注意が必要なんです」

「ああ……それは聞いたことがあるよ。 $0.1$ のような数は、コンピュータでは近似値としてしか扱えなくて、 何度も足していくと誤差が溜まっていくのでぴったり $1.0$ にはならない?」

テトラ「そうですね。 大雑把にいえばそういうことです。 この実行結果では、 $0.9999999999999999$ の次が $1.0999999999999999$ になっていて、すでに $1.0$ を越えちゃっています。 ですから、あとは $0.1$ をいくら足しても $x$ の値は増えるばかりで、 $1.0$ と等しくなることはありません」

「これは注意がいるなあ……あ、でもこれってプログラミング言語によって結果が異なるんじゃない?」

テトラ「そうですね。表示される内容はプログラミング言語に依存します。 しかし、 多くのプログラミング言語で無限ループになるんです」

「そうなんだ」

テトラ「はい。 表示される内容は《$x$ の値を表示する》という処理の実装で異なるかもしれませんが、 多くのプログラミング言語で無限ループになります。 浮動小数点数を扱う標準規格があって、 それに準拠じゅんきょしているなら、同様の現象になるはずです」

「標準規格?」

テトラ「ええと、確か……」

リサ「IEEE 754」

「うわっ!」

テトラ「きゃあっ!」

突然リサが声を出したので、テトラちゃんはびっくりした。

リサ「規格の名前」

テトラ「起きてたんですか?」

リサ「いま起きた」

リサは、いつものハスキーな声でそう言うと、 自分のコンピュータのスクリーンセーバを解除して何かをチェックし、 すばやくタイピング。

そしてまた腕組みをして目を閉じる。

テトラ「リサちゃん、お休みなさい」

リサ「《ちゃん》は不要」

「睡眠再開なんだね」

リサ「いまは《彼》が仕事中」

テトラ「彼?」

「彼?」

リサは目を開けることなく、自分の真っ赤なコンピュータを指さした。

テトラちゃんは顔を見合わせて苦笑する。

テトラ「先輩……あたしたち、何の話をしてましたっけ。Where were we?」

「無限ループの話だったかな」

テトラ「そうでした、そうでした……ともかく、 浮動小数点数を使ってループ終了の判定をするのはよくない方法です。 特に等式を使ってループ終了の判断をするのはよくありません。 せめて不等式を使うか、あるいはもっといいのは整数を使うことです」

「テトラちゃん、ずいぶん詳しいんだね」

テトラ「いえいえ。 たまたま、 そのあたりのことをいま勉強していただけです」

「ああ、リサちゃんと一緒に?」

リサをちらっと見た。

彼女は、腕を組んで目を閉じた姿勢に戻っている。

テトラ「あたしは、 AIエーアイさん に質問して学んでいました」

「へえ……」

AIとテトラちゃんの対話(その1)

テトラちゃんは、AIとの過去ログをに見せてくれた。

テトラ「こんにちは、AIさん」

AI「テトラさん、はじめまして! 今日はどのようなことでお手伝いしましょうか。どうぞお気軽に何でも質問してください」

「はじめまして?」

テトラ「先日、対話履歴とプロフィールをまちがって消しちゃったんです……なので、 AIさんはリセットされちゃいました。あたしのことも覚えていません」

彼女は、さみしげにそう言った。

は過去ログの続きを読む。

テトラちゃんAIの《対話》の記録だ。

テトラ「プログラムで $0.1$ を繰り返して足していくと $1.0$ にならないという現象について解説してください」

AI「コンピュータで $0.1$ を何回も足すと、 思った通りの結果にならないことがあります。 これはコンピュータが壊れてしまったわけではありません。 コンピュータは $0.1$ を正確に表すことができないからなんです。 正確な値との違いはほんの少しですから心配する必要はありませんが、 何度も繰り返すとその違いが大きくなってしまうんですよ。 コンピュータでプログラミングするときには、 さまざまな注意が必要になるんですね」

テトラ「ご説明ありがとうございます。 あたしはプログラミングのことを少し知っている高校生です。 きちんと学びたいと思っているので、 専門用語も含めてもう少し詳しく教えてください」

「なるほどね。このAIは、 テトラちゃんのことを忘れちゃったから、 ピント外れの回答をしてきたんだね」

テトラ「そうですね。 AIさんの回答は、 あたしの期待した方向とは少し違っていました。 ですから、あたしがどういうことを知っていて、どんなふうに回答してほしいかを改めて伝えました」

AI「テトラさん、わかりました。 それでは少し詳しく説明しますね。 コンピュータは数字を $2$ 進法で扱いますが、 $10$ 進法で表記した $0.1$ は $2$ 進法で表すと $$ 0.00011{}0011{}0011\ldots $$ のように、無限に続く小数になります。 でも、コンピュータの中では限られたビット数でしか数を保存できないので、 どこかで切って近い値にするしかありません。 このような仕組みで表された数は、 浮動小数点数と呼ばれます。 浮動小数点数で繰り返し計算すると、 もとの誤差が少しずつ積み重なって、 見た目にもズレが生じてしまうことがあります。 これは丸め誤差と呼ばれ、 プログラムを書く上でとても基本的な知識の一つです」

テトラ「細かいことかもしれませんが、 いまの説明で気になるところがあります。 AIさんは『コンピュータは数字を $2$ 進法で扱います』と説明しましたが、 『数字』というよりも『数値』ではないでしょうか」

AI「テトラさん、ご指摘ありがとうございます。 とても良い観察ですね。 確かに『数字』よりも『数値』のほうが適切な表現です。 『数字』は $0,1,2,3,\ldots,9$ のような文字あるいは記号のニュアンスが強く、 『数値』は量としての意味が強いからです」

「なるほどねえ……」

テトラ「どうしました?」

(2025年8月1日)

[icon]

結城浩(ゆうき・ひろし) @hyuki


『数学ガール』作者。 結城メルマガWeb連載を毎週書いてます。 文章書きとプログラミングが好きなクリスチャン。2014年日本数学会出版賞受賞。

Twitter note 結城メルマガ Mastodon Bluesky Threads Home