2015-10-20 105 views
1

据的YouTube link素因子奇数可以如下计算:费马算法素因子计算

A = SQRT(N + B^2)

我写以下程序要做到这一点,但我没有得到2345678917的主要因素。我知道这是素数,但对于其他素数,程序确实返回1和数字本身,但对于这个数字,它不会发生。为什么?

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

void foo(unsigned long long x) 
{ 
    int i; 
    for (i=1;i<x;i++) 
     if (fmod(sqrt(x + i*i), 1) == 0) { 
      printf("%f %f\n", (sqrt(x + i*i) - i), (sqrt(x + i*i)+i)); 
      return; 
     } 
} 

int main(void) { 
    foo((unsigned long long)2345678917); 
    return 0; 
} 
+0

此问题仍未解决,请继续并发布您的解决方案。 –

回答

2

首先,的iint)的类型不匹配xunsigned long long)。将i的类型更改为unsigned long long即可。

一旦你这样做了,你的程序会高兴地宣布14 * 167548494 = 2345678917.当然,这是不正确的,因为两个偶数的乘积不能是奇数。这里的问题是精度的损失,所以你需要为整数实现一个平方测试函数,而不是测试浮点平方根是否是整数。

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

unsigned long long find_sqrt(unsigned long long x) 
{ 
    unsigned long long lo = 1; 
    while (4 * lo * lo <= x) lo *= 2; 
    unsigned long long hi = 2 * lo; 
    while (lo + 1 < hi) { 
     unsigned long long mid = lo + (hi - lo)/2; 
     if (mid * mid <= x) lo = mid; 
     else hi = mid; 
    } 
    return lo * lo == x ? lo : 0; 
} 

void foo(unsigned long long x) 
{ 
    unsigned long long i; 
    for (i=1;i<x;i++) { 
     unsigned long long sqrt_x_ii = find_sqrt(x + i*i); 
     if (sqrt_x_ii) { 
      printf("%llu = %llu * %llu\n", 
        x, sqrt_x_ii - i, sqrt_x_ii + i); 
      return; 
     } 
    } 
} 

int main(void) { 
    foo((unsigned long long) 2345678917); 
    return 0; 
} 
+0

不起作用http://ideone.com/iVRDlI –

+0

是的,它要么很慢,要么停留在inf循环中,我没有在调试器中停下来检查。这可能是因为它很长一段时间没有找到任何确切的sqrt。 –

+0

@nomanpouigt:'2345678917 + i * i'是一个正方形的最小'i'是'1172839458'。对于计算超过10亿个整数平方根需要超过5秒钟,您不应该感到惊讶。无论如何,这个答案给出了基本的信息:即,你遇到了浮点精度的困难。请注意,对于'i'的值,'2345678917 + i * i'是'1375552396587412681',它不能完全用IEEE 754 binary64 double(这可能是您的平台使用的)来表示。 –