ABC139のD問題をPythonで解いたときにハマったやつ
備忘録です。
まずは誤答例のソースコード
#WA N = int(input()) print(int(N*(N-1)/2))
次に正答例のソースコード
#AC N = int(input()) print(N*(N-1)//2)
はい?なにが違うの??
種明かし
誤答例だと一度浮動小数点数を経由しているのがまずいです。どういうことかわかりやすく示したのが次のコード。
ans = 0 for i in range(1,20): print(float(ans)) ans*=10 ans += i%10
出力結果
0.0 1.0 12.0 123.0 1234.0 12345.0 123456.0 1234567.0 12345678.0 123456789.0 1234567890.0 12345678901.0 123456789012.0 1234567890123.0 12345678901234.0 123456789012345.0 1234567890123456.0 1.2345678901234568e+16 1.2345678901234568e+17
このように、保持可能な仮数より大きな仮数は丸められてしまうわけです。元の問題に戻ると、Nが大きすぎる(例えばN=999999999)場合には誤差が生じてしまうということです。実際に実行してみると以下のようになります。
#N=999999999 N = int(input()) print("N1 =",int(N*(N-1)/2)) print("N2 =",N*(N-1)//2)
出力結果
N1 = 499999998500000000 N2 = 499999998500000001
型が自動的にキャストされるのは便利ですが、バグの原因にもなる得るということでしょうか...。