見出し画像

京大Python教科書、平方根を求める

タイトルの「京大Python教科書」というのはこちら。

前回はPythonの環境構築まで書いた。
(前回が既に3ヶ月近く前…)

今回はいよいよプログラミングである。



いよいよプログラミングする

「3.変数と演算,代入」は、実にありがちなタイトルである。プログラミングの基本中の基本であるが、どうしても抽象的になりがちであまり面白くないかもしれない。こんなところでモタモタしていてもプログラミングが嫌いになるだけだろう。たくさんプログラムを書いて体得してくれ。というわけで、本章はスキップする。

次。

「4.例題:平方根を求める」

これはまた。「おや?」と思ったりする。Pythonは数学ライブラリも充実しているから、おそらく平方根を求めるライブラリもあるだろう(知らんけど)。だがここでは、それを使って平方根を求めようというのでは、もちろんない。ライブラリの使い方をマスターするのが目的ではないからだ。以前にも書いたのだが、CPUができる演算というのは極めて限られている。四則演算と論理演算、あとはビット演算くらいだろうか。たったそれだけのことしかできない。そして当然のことながら、この教科書でも、四則演算だけで平方根を求めているのである。面白いと思いませんか? 


平方根、どうやって求める?

平方根を求めるとするとどういう計算が思い付くだろうか。例えば、2の平方根というのは、2乗したら2になる数である。多くの人はだいたいの数値を知っているだろう。

ひとよひとよにひとみごろ
1.41421356

である。

ものすごく究極的なやりかたであるが、例えば

0から順に0.00000001ずつ足していく

というのはどうだろう。
2乗してみて、2を超えるまで計算し続けるんである。

こんな感じだ。

for r in range(0.0, 2.0, 0.00000001):
    if 2 <= (r * r):
        break

print('{:.15f}'.format(r))

range というのは Python の組み込み関数で import することなく使うことができる。

for r in range(0.0, 2.0, 0.00000001)

というのは

r を 0.0 から 0.00000001 ずつ足して 2.0 まで繰り返す

ということを意味する。

if 2 <= (r * r):
    break

これは、次の意味になる。

r の2乗が 2 以上になったら繰り返しをやめる

すなわち、
0.00000001
0.00000002
0.00000003

を順に2乗していって、2以上になるのを探す
ということをしているのである。


コンピューターは繰り返しがお好き

こんなこと、人間にはできない。
人間は同じことの繰り返しが苦手である。
だんだんと単調になってきて、退屈になってきて、飽きてくる。

と、こ、ろ、が。

コンピュータというのは繰り返しが得意中の得意でなんある。繰り返せと言われればひたすら繰り返す。繰り返しをやめろというまで何度でも繰り返す。やめろといわなければ無限に繰り返す。これを無限ループという。

なので 141,421,356 という 1億4000万回を超える繰り返しだってへっちゃらである。

さあ、やってみよう。


エラーになっちゃったんですけど

書いたプログラムはこれ。

for r in range(0.0, 2.0, 0.00000001):
    if 2 <= (r * r):
        break

print('{:.15f}'.format(r))

実行してみる。

~/python/kyoto $ python root-01.py
Traceback (most recent call last):
  File "/data/data/com.termux/files/home/python/kyoto/root-01.py", line 1, in <module>
    for r in range(0.0, 2.0, 0.00000001):
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'float' object cannot be interpreted as an integer
~/python/kyoto $

あ?
エラーってか?(笑)

エラーの内容はちゃんと読むべし。
ちゃんと読んでも意味不明なこともないではない。ないではないが、だがしかし。それにしても、最近は「なんかエラーが出るんですけど」というだけの問題報告がいささか多い気がする。せめてもう少しは具体的に、何をどうやったらどんなエラーがでたのかを報告してほしい。そんな風に「問題現象を具体化する」ということは問題解決の第一歩である。そこを疎かにしていては解決できる問題も解決できない。

今回の場合、Pythonはこう言っている。

TypeError: 'float' object cannot be interpreted as an integer

先頭のコレ→「TypeError」。
これだけで概ね予想もつく。
型のエラーだ。
え?
型のエラー?
さっき「3.変数と演算,代入」をスキップしちゃったんですけど。

つか、Pythonに型がありや?
int も char もなかろうに。

残りのエラーメッセージも読んでみる。

'float' object cannot be interpreted as an integer

一応日本語に訳してみる。

'float' オブジェクトは整数として解釈できません

ちっ。(ついつい、下品になっちまう)
range は浮動小数点が使えんのか。
わからんではないが。
初心者がここにぶちあたるとどうなるんだろう。

「float」とかいう、中に浮いたような単語は何?

とでもなるのだろうか。
そして、とにかくネット検索してみる。

いや、そりゃそうなる。
検索し直す。

うーん。
実数を扱うことができる、とな。
てか、ごく普通に実数を扱えんのか?

プログラミングで「float型」を蘊蓄していると面倒臭いところにはまるので、とにかくこれだけを覚えておく。

プログラミングで小数を扱うのは面倒臭い

話を戻すと「range」というのはPythonの組み込み関数なんだが、この関数は「float」を扱わない、ようするに小数は使えないということだ。

あ、そう。

わかったわよ。
書き直すわよ。


rangeに小数を使わなきゃいいんでしょ!

書き直してみた。

r = 0

# iに1ずつ足しながら10億回繰り返す。
for i in range(1, 1000000000, 1):
    # 平方根rは0.00000001ずつ足していく。
    r += 0.00000001

    # rの2乗が2以上になったら、繰り返しを終了する。
    if 2 <= (r * r):
        break

# rを小数点以下15桁まで表示する。
print('{:.15f}'.format(r))

これでどうよ。

~/python/kyoto $ python root-03.py
1.414213569772496
~/python/kyoto $

動くには動いたけど、40秒近くかかっちゃったわよ。

さすがに1億4000万回の繰り返しは多すぎるか。

はて。

(つづく)


この記事が気に入ったらサポートをしてみませんか?