(Project Eulerについてのネタバレを含みます)
Project Eulerの16を解いていた。
やってること自体は単純で2^1000をひたすら0になるまで10で割った余りを出してそれを足して元の数を10で割ることを繰り返すだけ、なのだけど...
最初に作ったのがこれ
a = 2**1000
print(a)
sum = 0
while a>0:
b = a % 10
sum += b
a = int(a / 10)
print(sum)
これだと出力が
1189
となる。しかしこれは正しい答えではなくて困惑してしまった。そこで調べてみてこんなものを見つけた。
https://paiza.hatenablog.com/entry/2017/08/01/Python3%E3%81%A7%E5%B7%A8%E5%A4%A7%E3%81%AA%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E8%A8%88%E7%AE%97%E3%81%AE%E7%B5%90%E6%9E%9C%E3%81%8C%E5%A4%89%E3%81%A0%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A7%E7%90%86
これによるとfloat型だと大分計算の誤差が発生してしまうらしい。int(a / b)
という書き方を結構使っていた(つまりfloat型で計算→int型に変換)自分としては衝撃的な記事だった。これからは//
を使っていこうと反省。
コードを以下のように書き換えた。
a = 2**1000
print(a)
sum = 0
while a!=0:
b = a % 10
sum += b
a = a // 10
print(sum)
すると以下の通り、計算結果がだいぶ違うことが分かる。
1366
こちらは正解だったのでやはりintで通すべきだったのだろう。誤差って怖いと改めて感じた。