- - PR -
Fermatの最終定理
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2008-01-07 15:37
現在、Fermatの最終定理をプログラムを組んで証明しようとしています。もちろん自然数は無限大にあるわけですから限界があることはわかっていますのでできるところまでという目標のもとやっています。
現在、下のようなプログラムをJavaを用いて組んで走らせてみているのですが、nが16の段階で式が成り立ってしまうという現象が起きてしまっています。たぶんなのですが、double型を用いてるために10^16という数値が限界を超えてしまって計算結果がおかしくなってしまっているのだと思うのですが、いまいち解決の仕方がわかりません。どなたかご助言をお願いします。 /*Javaプログラム*/ import java.lang.Math; public class Jikkou { public static void main(String[] args){ double n,x,y,z; System.out.println("n x y z"); for(n=2;n<=20;n++){ for(x=1;x<=10;x++){ for(y=1;y<=x;y++){ for(z=1;z<=(x+y);z++){ if(Math.pow(x,n)+Math.pow(y,n)==Math.pow(z,n)){ System.out.println(Math.pow(x,n)+"+"+Math.pow(y,n)+"=="+Math.pow(z,n)); System.out.println(n+" "+x+" "+y+" "+z); } } } } } } } /*実行結果*/ n x y z 16.0+9.0==25.0 2.0 4.0 3.0 5.0 64.0+36.0==100.0 2.0 8.0 6.0 10.0 1.0E16+1.0==1.0E16 16.0 10.0 1.0 10.0 1.6677181699666568E16+1.0==1.6677181699666568E16 17.0 9.0 1.0 9.0 1.0E17+1.0==1.0E17 17.0 10.0 1.0 10.0 1.8014398509481984E16+1.0==1.8014398509481984E16 18.0 8.0 1.0 8.0 1.50094635296999136E17+1.0==1.50094635296999136E17 18.0 9.0 1.0 9.0 1.0E18+1.0==1.0E18 18.0 10.0 1.0 10.0 1.1398895185373144E16+1.0==1.1398895185373144E16 19.0 7.0 1.0 7.0 1.44115188075855872E17+1.0==1.44115188075855872E17 19.0 8.0 1.0 8.0 1.350851717672992E18+1.0==1.350851717672992E18 19.0 9.0 1.0 9.0 1.0E19+1.0==1.0E19 19.0 10.0 1.0 10.0 7.9792266297612E16+1.0==7.9792266297612E16 20.0 7.0 1.0 7.0 1.15292150460684698E18+1.0==1.15292150460684698E18 20.0 8.0 1.0 8.0 1.2157665459056929E19+1.0==1.2157665459056929E19 20.0 9.0 1.0 9.0 1.0E20+1.0==1.0E20 20.0 10.0 1.0 10.0 | ||||
|
投稿日時: 2008-01-07 15:52
たぶん、誤差でしょう。
doubleは1bitの負号、11bitの指数部、52bitの仮数部を持ちます。 52bit = 10bit ^ 5 + 2bit ≒ 10 ^ 3 ^ 5 * 4 = 4 * 10 ^ 15 程度までは仮数部の精度から整数は誤差なく表現できることが期待できますが それ以上の数値については誤差で整数を隙間なく表現することができないでしょう。 整数でそれなりの大きさまで扱えればいいというのであれば longを用いることで63bitの大きさで整数を扱えますし、 それ以上の精度が必要であればjava.math.BigDecimalを用いましょう。 | ||||
|
投稿日時: 2008-01-07 16:39
java.math.BigInteger(任意精度の整数)を使えばよいです。
| ||||
|
投稿日時: 2008-01-07 17:11
質問者の方は、おわかりになっていると思いますが、 プログラムで<<証明>>はできません。 「フェルマーの最終定理」サイモン・シン著 は、かなりおもしろかったです。 もし、読んでいなければ一読をお勧めいたします。 (この本の中でも、コンピュータを使って<<証明>>することはできない。 と書かれています。 定理に反する解を見つけられたら、その定理が成立しないことは証明できますが、 定理に反する解を見つけられないからといって、その定理が成立するとは言えません。 その例についても、本の中で触れられています。) | ||||
|
投稿日時: 2008-01-07 18:20
nagiseさん
詳しい解説ありがとうございます。やはりdouble型では限界があるのですね。 java.math.BigDecimalというのは初めて知りました。調べてみたいと思います。 >blunderさん さっそく調べさせてもらいました。多倍長整数というものがあるのですね。こんな便利なものがあるとは、勉強になりました。ありがとうございます。 >yuzyさん わかってはいるのですが、証明というものが昔から苦手でしてww 擬似的にでもプログラムでできればと思いやってみた次第ですw お勧めいただいた本は早速図書館に行って探してみたいと思います。 ありがとうございました。 | ||||
|
投稿日時: 2008-01-07 18:27
みなさんのご助言のもと改良したプログラムによって、何とか正常に動かすことが可能となりましたので、計算結果とともにのせておきます。へたれなプログラムですがご容赦くださいw
/*改良したプログラム*/ import java.math.*; public class Jikkou { public static void main(String[] args){ int n; //冪乗の値 int x,y,z;//X^n+Y^n=Z^nの式内の変数にそれぞれ対応 int count=0;//試行回数のカウント用 for(n=2;n<=100;n++){//何乗まで計算するか for(x=1;x<=100;x++){//xの値の範囲の決定(1〜?) for(y=1;y<=x;y++){//yの値の範囲の決定(1〜x) for(z=x;z<=(x+y);z++){//zの値の範囲の決定(x〜x+y) /*現在のx,y,zを用いて多倍長整数X,Y,Zを生成*/ BigInteger X = new BigInteger(Integer.toString(x)); BigInteger Y = new BigInteger(Integer.toString(y)); BigInteger Z = new BigInteger(Integer.toString(z)); /*X^n+Y^n=Z^nの式が成り立つかの判定*/ if(X.pow(n).add(Y.pow(n)).equals(Z.pow(n))){//pow(n)はBigIntegerクラスが持つn乗を計算するクラスメソッド /*デバッグと途中経過表示用*/ System.out.println(X.pow(n)+"+"+Y.pow(n)+"=="+Z.pow(n)); System.out.println("n="+n+" "+"x="+x+" "+"y="+y+" "+"z="+z); } /*試行回数をインクリメント*/ count++; } } } } /*結果表示用*/ System.out.println("試行回数"); System.out.println(count); } } /*計算結果*/ 16+9==25 n=2 x=4 y=3 z=5 64+36==100 n=2 x=8 y=6 z=10 144+25==169 n=2 x=12 y=5 z=13 144+81==225 n=2 x=12 y=9 z=15 225+64==289 n=2 x=15 y=8 z=17 256+144==400 n=2 x=16 y=12 z=20 400+225==625 n=2 x=20 y=15 z=25 441+400==841 n=2 x=21 y=20 z=29 576+49==625 n=2 x=24 y=7 z=25 576+100==676 n=2 x=24 y=10 z=26 576+324==900 n=2 x=24 y=18 z=30 784+441==1225 n=2 x=28 y=21 z=35 900+256==1156 n=2 x=30 y=16 z=34 1024+576==1600 n=2 x=32 y=24 z=40 1225+144==1369 n=2 x=35 y=12 z=37 1296+225==1521 n=2 x=36 y=15 z=39 1296+729==2025 n=2 x=36 y=27 z=45 1600+81==1681 n=2 x=40 y=9 z=41 1600+900==2500 n=2 x=40 y=30 z=50 1764+1600==3364 n=2 x=42 y=40 z=58 1936+1089==3025 n=2 x=44 y=33 z=55 2025+576==2601 n=2 x=45 y=24 z=51 2025+784==2809 n=2 x=45 y=28 z=53 2304+196==2500 n=2 x=48 y=14 z=50 2304+400==2704 n=2 x=48 y=20 z=52 2304+1296==3600 n=2 x=48 y=36 z=60 試行回数 2314125 | ||||
|
投稿日時: 2008-01-08 00:05
興味でやっていることに水を差すつもりはありませんが、少しだけ補足します。
(1) 「フェルマーの最終定理」という呼称は正しくありません。 「フェルマー予想」あるいは「ワイルズの定理」です。 (2) n=2 の場合、x^2+y^2=z^2 を満たす整数解は以下の式で尽くされます。(これ以外に解はなく、すべての解はこの形で表現できる) 任意の整数 m, n に対して x=m^2-n^2 y=2*m*n z=m^2+n^2 |
1