C++ 确定平方根是否为整数

C++ 确定平方根是否为整数,c++,arrays,loops,math,sqrt,C++,Arrays,Loops,Math,Sqrt,在我的程序中,我正试图利用这个函数来找到数字600851475143中的最大素因子。我制作了一个for循环,用于确定该数字的所有因子,并将它们存储在向量数组中。我遇到的问题是,我不知道如何确定因子是否可以平方根,并给出一个整数而不是小数。到目前为止,我的代码是: #include <iostream> #include <vector> #include <math.h> using namespace std; vector <int> fac

在我的程序中,我正试图利用这个函数来找到数字600851475143中的最大素因子。我制作了一个for循环,用于确定该数字的所有因子,并将它们存储在向量数组中。我遇到的问题是,我不知道如何确定因子是否可以平方根,并给出一个整数而不是小数。到目前为止,我的代码是:

#include <iostream>
#include <vector>
#include <math.h>

using namespace std;
vector <int> factors;

int main()
{
    double num = 600851475143;
    for (int i=1; i<=num; i++)
    {
        if (fmod(num,i)==0)
        {
            factors.push_back(i);
        }
    }

     for (int i=0; i<factors.size(); i++)
     {
         if (sqrt(factor[i]))                      // ??? 
     }
}
#包括
#包括
#包括
使用名称空间std;
矢量因子;
int main()
{
双数=600851475143;
对于(int i=1;i
正如霍布斯在评论中指出的

假设double是常见的64位IEEE-754双精度浮点,对于小于2^53的值,一个double和下一个可表示的double之间的差值小于或等于1。大于2^53,精度比整数差

bool isSquareNumber(int n){
    int l=1, h=n;
    while(l<=h){
        int m = (l+h) / 2;
        if(m*m == n){
            return true;
        }else if(m*m > n){
            h = m-1;
        }else{
            l = m+1;
        }
    }
    return false;
}

int main()
{
   // ......
     for (int i=0; i<factors.size(); i++){
         if (isSquareNumber(factor[i]) == true){
              /// code
         }
     }
}

因此,如果int为32位,则是安全的。如果必须处理大于2^53的数字,则可能会出现一些精度错误。

以下方法应该可以工作。它利用了整数截断

if (int (sqrt(factor[i])) * int (sqrt(factor[i])) == factor[i])

它之所以有效,是因为非平方数的平方根是十进制数。通过转换为整数,可以删除双精度的小数部分。一旦将其平方,它就不再等于原始平方根。

与cero进行比较时,还必须考虑舍入误差。如果编译器支持,则可以使用std::round端口c++11,如果没有,您可以自己做()

#包括
#包括
#包括
使用名称空间std;
矢量因子;
int main()
{
双数=600851475143;

对于(int i=1;i完美平方只能以16进制的0、1、4或9结尾,因此对于75%的输入(假设它们是均匀分布的),您可以避免调用平方根来交换一些非常快速的位旋转

int isPerfectSquare(int n)
{
    int h = n & 0xF;  // h is the last hex "digit"
    if (h > 9)
        return 0;
    // Use lazy evaluation to jump out of the if statement as soon as possible
    if (h != 2 && h != 3 && h != 5 && h != 6 && h != 7 && h != 8)
    {
        int t = (int) floor( sqrt((double) n) + 0.5 );
        return t*t == n;
    }
    return 0;
}
用法:

for ( int i = 0; i < factors.size(); i++) {
   if ( isPerfectSquare( factor[ i]))
     //...
}
for(int i=0;i

你问错了问题。你的算法是错误的。(好吧,不完全是错误的,但如果按照所提出的想法进行纠正,它将是非常低效的。)使用你的方法,你还需要递归地检查立方体、五次幂和所有其他素数幂。例如,尝试找到5120=5*2^10的所有因子


更简单的方法是在通过除法找到因子后将其删除

num=num/i
然后,如果迭代遇到一些i=j^2或i=j^3,…,所有的因子j,如果有的话,在我有值j的早期阶段已经被移除了,并在因子数组中进行了说明



您还可以提到这是来自Euler项目的问题3。那么您可能已经找到了最近的讨论“”这里讨论了分解算法的更有效的变型。< /P> < P>这里是一个简单的C++函数,用于确定一个数是否具有整数平方根:

bool has_sqrtroot(int n)
{
    double sqrtroot=sqrt(n);
    double flr=floor(sqrtroot);
    if(abs(sqrtroot - flr) <= 1e-9)
        return true;

    return false;
}
bool有\u sqrtroot(int n)
{
双sqrtroot=sqrt(n);
双flr=地板(平方根);
如果(abs(sqrtroot-flr)Assqrt()函数与浮点一起工作,则最好避免使用其返回值(由于精度错误,浮点计算有时会给出错误的结果)。相反,您可以编写一个函数-isSquareNumber(int n),它将决定该数字是否为平方数,整个计算将以整数进行

bool isSquareNumber(int n){
    int l=1, h=n;
    while(l<=h){
        int m = (l+h) / 2;
        if(m*m == n){
            return true;
        }else if(m*m > n){
            h = m-1;
        }else{
            l = m+1;
        }
    }
    return false;
}

int main()
{
   // ......
     for (int i=0; i<factors.size(); i++){
         if (isSquareNumber(factor[i]) == true){
              /// code
         }
     }
}
bool-isSquareNumber(int-n){
int l=1,h=n;
while(l n){
h=m-1;
}否则{
l=m+1;
}
}
返回false;
}
int main()
{
// ......

对于(int i=0;iYep。这应该适用于
因子[i]
高达2^53左右。是的,因为因子是int的向量,所以我们是安全的。我们所知道的
int
可能是64位的。:)但是我想你的2^53限制也会提高。顺便说一句,你从哪里得到的?假设
double
是通常的64位IEEE-754双精度浮点,对于小于2^53的值,一个
double
和下一个可表示的
double
之间的差值小于或等于1。高于2^53,精度为wor这个问题的可能重复是Euler项目3号,最后一次在这里讨论:我不认为“十进制”是正确的词,因为我们不是在讨论字符串。谢谢。虽然小数部分有意义,但它不是正确的表达方式。我必须查找小数点前后的数字。显然,一种被接受的方法是小数部分。找到了答案。
if(((1))
bool isSquareNumber(int n){
    int l=1, h=n;
    while(l<=h){
        int m = (l+h) / 2;
        if(m*m == n){
            return true;
        }else if(m*m > n){
            h = m-1;
        }else{
            l = m+1;
        }
    }
    return false;
}

int main()
{
   // ......
     for (int i=0; i<factors.size(); i++){
         if (isSquareNumber(factor[i]) == true){
              /// code
         }
     }
}