2014年6月2日月曜日

140602

誤差について


140315(2)について、数学的には正しいが、プログラミングのうえでは不完全な部分があった。

z = Math.sqrt(x**2+y**2)
  if z == z.to_i && z < 101 then

上記はzが整数になるときについて考えようとしているわけだが、
x**2+y**2が平方数に非常に近い場合、(数学的にz == z.to_i が偽であっても)
z == z.to_i が真となりうる。
よって、
z = Math.sqrt(x**2+y**2)
  if x**2+y**2 == (z.to_i)**2 && z < 101 then
とすべきである。

このことは、次のフェルマーが出した問題を解いているときに気づいた。
x^2 - 61y^2 = 1 の自然数解を求めよ。

y = 1
num = Math.sqrt(61*y**2+1)
while !(num == num.to_i)
  y += 1
  num = Math.sqrt(61*y**2+1)
end
p num
p y

とすると、誤った最小の自然数解
335159612.0
42912791
が出力される。
正しくは次のとおりである。

y = 1
num = Math.sqrt(61*y**2+1)
while !((num.to_i)**2 - 61*y**2 == 1)
  y += 1
  num = Math.sqrt(61*y**2+1)
end
p num
p y

出力結果
1766319049.0
226153980

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。