2013-03-10 66 views
0

我已經正常工作。 代碼 -C語言 - 費馬理論驗證器無法正常工作

#include <stdio.h> 
#include <math.h> 

int quadtest(unsigned long long int a, unsigned long long int b, unsigned long long int c,  unsigned int n) 
{ 
    if ((pow(a,n)+pow(b,n))==pow(c,n)) 
     return 1; 
    else 
     return 0; 
} 

main() 
{ 
unsigned long long int a; 
unsigned long long int b; 
unsigned long long int c; 
unsigned int n; 

n=3; 
for(n; n<50; n++) 
{ 

//printf("\nn=%u",n); 
    for(c=2; c<500; c++) 
    { 

     printf("\ntrying now c=%llu and n=%u",c,n);  
     for(b=2; b<500; b++) 
     { 
      for(a=2; a<500; a++) 
      { 
       quadtest(a,b,c,n); 
       if (quadtest(a,b,c,n)==1) 
       { 
        printf("\n|||||||||||||||||||||||WORKS|||||||||||||||||||||||||||||||||"); 
        break; 
       } 
       //printf("\na=%llu, n=%u b=%llu c=%llu",a,n,b,c); 

      } 
     if (quadtest(a,b,c,n)==1) 
     break;} 

     if (quadtest(a,b,c,n)==1) 
     break; 
    } 
    if (quadtest(a,b,c,n)==1) 
    break; 
}  
if (quadtest(a,b,c,n)==1) 
printf("\nthe correct values are a=%llu,b=%llu,c=%llu,n=%u",a,b,c,n); 
else 
printf("\nfermats theory is correct"); 
} 

從我的立場,我正確編碼的一切,(我只用了50範圍內和500,所以我其實可以在我的電腦上運行它,沒有它字面上每天服用)。所以我編譯了Cygwin中的程序(我需要使用它),花了大約15分鐘左右,然後停在「正確的值是a = 381,b = 2,c = 381,n = 7 「這顯然是不正確的。我不確定問題是什麼或如何解決這個問題。我認爲它與記憶有關,但我仍然不確定這是一個什麼樣的解決方案。

+0

我是這麼認爲的,我不是肯定的是什麼使我對範圍內解決這個問題。我想改變b <500到pow(b,n)小於一個數字,但我不確定那個數字是多少。 – Alex 2013-03-10 22:16:15

+1

@Alex問題是'pow()'對不精確的浮點數進行操作。使用重複乘法實現您自己的冪函數,它將起作用。 – 2013-03-10 22:17:12

+0

@Alex使用'unsigned long long',除了浮點值精度有限的問題之外,您很快就會發生溢出。如果你想運行一個正確的蠻力,你需要bignums。 – 2013-03-10 22:19:54

回答

1

pow()接受雙重參數並返回double。雙精度有限(通常使用64位)。存在一個double x,使得(x + 1.0)== x。這基本上就是你所遇到的,因爲381 ** 7是一個非常大的整數。

爲了正確執行這種計算,您需要一種方法來對大整數進行精確的數學運算。你需要的通常被稱爲「bignum」庫。 GMP就是這樣,你可能想要檢查一下。

+0

我是否可以將限制更改爲a,b,c的其他值?老師從來沒有教過那麼高的素質,所以我很確定他不希望我們這樣做。會讓我自己的電源功能起作用嗎? – Alex 2013-03-10 22:20:48

+0

如果這是家庭作業,那麼老師是否有可能希望您瞭解C語言中的類型的精度有限,以及爲什麼顯而易見的解決方案會失敗?在C語言中,除非你自己推出了bignum庫,否則你會遇到編寫自己的電源函數的問題。如果你堅持整數類型,你會得到一個不同類型的問題 - 溢出。沒有n這樣(n + 1)== n,但是有一個n使得(n + 1) svk 2013-03-10 22:24:53

+0

那麼它的功課,但它不懂數據類型精度有限。即時通訊不確定不幸的是什麼貴族。 – Alex 2013-03-10 22:32:29

2

由於您正在處理雙打(pow()返回雙倍), 最好通過使用EPSILON進行比較,如下所示。 通過計算兩個變量之間的差異,您可以創建一個「小」雙(例如double EPSILON = 0.001) 並與雙打比較。

double a,b; 
if(abs(a - b)) < EPSILON){ 
    /* your code here.. 
} 

其重要的使用功能abs(),所以你不必擔心 如果(a > b) || (b < a)

爲了獲得更好的效果,你可以選擇較小EPSILON

這樣寫:

if ((pow(a, n) + pow(b, n) - pow(c, n)) < EPSILON) { 
    return 1;