Ton*_*ion 5 c++ math factorization
为了好玩,我一直用C++实现一些数学习题,而且我一直在尝试实现Fermats Factorisation Method,但是,我不知道我理解它应该返回什么.我有这个实现,返回105维基百科文章中给出的示例号5959.
维基百科中的伪代码如下所示:
一个尝试a的各种值,希望这是一个正方形.
FermatFactor(N): // N should be odd
a ? ceil(sqrt(N))
b2 ? a*a - N
while b2 isn't a square:
a ? a + 1 // equivalently: b2 ? b2 + 2*a + 1
b2 ? a*a - N // a ? a + 1
endwhile
return a - sqrt(b2) // or a + sqrt(b2)
Run Code Online (Sandbox Code Playgroud)
我的C++实现,如下所示:
int FermatFactor(int oddNumber)
{
double a = ceil(sqrt(static_cast<double>(oddNumber)));
double b2 = a*a - oddNumber;
std::cout << "B2: " << b2 << "a: " << a << std::endl;
double tmp = sqrt(b2);
tmp = round(tmp,1);
while (compare_doubles(tmp*tmp, b2)) //does this line look correct?
{
a = a + 1;
b2 = a*a - oddNumber;
std::cout << "B2: " << b2 << "a: " << a << std::endl;
tmp = sqrt(b2);
tmp = round(tmp,1);
}
return static_cast<int>(a + sqrt(b2));
}
bool compare_doubles(double a, double b)
{
int diff = std::fabs(a - b);
return diff < std::numeric_limits<double>::epsilon();
}
Run Code Online (Sandbox Code Playgroud)
应该归还什么?它似乎只是回归a + b,这不是因素5959?
编辑
double cint(double x){
double tmp = 0.0;
if (modf(x,&tmp)>=.5)
return x>=0?ceil(x):floor(x);
else
return x<0?ceil(x):floor(x);
}
double round(double r,unsigned places){
double off=pow(10,static_cast<double>(places));
return cint(r*off)/off;
}
Run Code Online (Sandbox Code Playgroud)
请注意,您应该对整数类型而不是浮点类型进行所有这些计算。这会简单得多(而且可能更正确)。
你的compare_doubles函数是错误的。diff应该是一个double.
一旦你解决了这个问题,你就需要修复你的测试线。compare_doubles如果其输入“几乎相等”,将返回 true。当它们“不几乎相等”时,您需要循环。
所以:
bool compare_doubles(double a, double b)
{
double diff = std::fabs(a - b);
return diff < std::numeric_limits<double>::epsilon();
}
Run Code Online (Sandbox Code Playgroud)
和:
while (!compare_doubles(tmp*tmp, b2)) // now it is
{
Run Code Online (Sandbox Code Playgroud)
您将得到101该输入的正确结果 ( )。
正如vhallac指出的那样,您还需要使用as “places”round来调用您的函数- 您不应该四舍五入到小数点后一位数字。0
您链接的维基百科文章有一个方程式,可以让您识别b和N。a-b