C 查找从2到上限的所有友好数字对-输出不正确

C 查找从2到上限的所有友好数字对-输出不正确,c,function,output,C,Function,Output,我试图写一个函数,它能找到从2到给定上限的所有友好数对 我写了一个函数,求给定数的除数之和 我还编写了一个函数,它使用这样一个事实:如果num1的除法器之和是S(num1),并且num2=S(num1)-num1具有相同的除法器之和,那么num1和num2是友好的数 这是我的密码: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> void amicableNumbers(int

我试图写一个函数,它能找到从2到给定上限的所有友好数对

我写了一个函数,求给定数的除数之和

我还编写了一个函数,它使用这样一个事实:如果num1的除法器之和是S(num1),并且num2=S(num1)-num1具有相同的除法器之和,那么num1和num2是友好的数

这是我的密码:

#define _CRT_SECURE_NO_WARNINGS

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

void amicableNumbers(int n);
int findSumOfDevisors(int num);

void main() {
    int upperRange;

    printf("enter the value for upper range: ");
    scanf("%d", &upperRange);
    printf("the amicable numbers between 2 and %d:\n", upperRange);
    amicableNumbers(upperRange);
}

void amicableNumbers(int n) {
    int sum, sum2, i;

    for (i = 2; i <= n; i++) {
        sum = findSumOfDevisors(i);
        if (sum > i && sum <= n) {
            sum2 = findSumOfDevisors(sum);
            if (sum2 == i)
                printf("%d and %d \n", i, sum);
        }
    }
}

int findSumOfDevisors(int num) {
    int sum = 1, i, n;
    
    n = (int)sqrt((double)num);
    for (i = 2; i <= n; i++) {
        if ((n % i) == 0) {
            sum += i;
            sum += n / i;
        }
    }
    return sum;
}
\define\u CRT\u SECURE\u NO\u警告
#包括
#包括
无效友好号码(int n);
int findSumofDevisor(int num);
void main(){
整数上限;
printf(“输入上限值:”);
scanf(“%d”和上限);
printf(“介于2和%d:\n之间的友好数字”,上限);
友好数字(上限);
}
无效友好号码(整数n){
int sum,sum2,i;

对于(i=2;i i&&sum您的
findsumofdevisiors
函数是错误的。此外,IMO
sqrt()
函数在性能上是压倒性的。相反,您应该使用
i此函数存在问题

int findSumOfDevisors(int num)
这是一个输入错误,你想输入num而不是n 正确的功能是

int findSumOfDevisors(int num)
{
int sum = 1, i,n;

 n =(int) sqrt((double)num);
for (i = 2; i <= n; i++)
{
    if ((num % i) == 0)
    {
        sum += i;
        sum += num / i;
    }
}
return sum;
}
int findsumofdevisor(int num)
{
int sum=1,i,n;
n=(int)sqrt((double)num);

for(i=2;iOP的
findsumofdevisiors()
有问题。也许其他代码也有问题

  • sqrt()
    没有义务给出准确的平方根-一些较弱的实现可能会导致值刚好高于或低于预期答案。再加上
    (int)
    这会截断分数,像123.99999999这样的答案会变成123而不是124。无论如何,这里不需要浮点数学及其精度问题

    建议仅使用整数数学:

    // n =(int) sqrt((double)num);
    // for (i = 2; i <= n; i++)
    for (i = 2; i <= num/i; i++)
    
  • 为了完整性,我希望
    findSumOfDevisors(0)
    findSumOfDevisors(1)
    返回0,而不是像OP的代码一样返回1。负数是另一个未解决的问题

    // int sum = 1;
    int sum = num > 1;
    
  • < > LI> < P>使用昂贵的<代码> /,%< /代码>或获得2个-1,考虑下面的代码。<代码> %和<代码> /<代码>每个调用潜在地有一个昂贵的余数和除法计算。但是有许多好的编译器,<代码> NUM/I 和<代码> num %i <代码>将导致发射代码来计算两个OPER中的两个代码。为了清晰起见,最好编写代码,但是如果永久性是一个问题,那么请调查一个好的优化编译器的结果

    for (i = 2; i < num/i; i++) {
      if (num%i == 0) {
    
    for(i=2;i

    不建议在
    findSumofDivisor
    中使用浮点运算,请尝试以下操作:

    int findSumOfDivisors(int num) {
        int sum = 1, div, i;
    
        for (i = 2; i <= (div = num / i); i++) {
            if (num % i == 0) {
                sum += i;
                if (i == div)
                    break;
                sum += div;
            }
        }
        return sum;
    }
    
    最后,没有参数的
    main
    的原型是
    intmain(void)
    ,您应该测试
    scanf()的返回值
    ,并从
    main
    返回
    0

    以下是一个改进的版本:

    #include <stdio.h>
    
    int findSumOfDivisors(int num) {
        int sum = 1, div, i;
    
        for (i = 2; i <= (div = num / i); i++) {
            if (num % i == 0) {
                sum += i;
                if (i == div)
                    break;
                sum += div;
            }
        }
        return sum;
    }
    
    void amicableNumbers(int n) {
        int sum, i;
    
        for (i = 2; i <= n; i++) {
            sum = findSumOfDivisors(i);
            if (sum > i && sum <= n && findSumOfDivisors(sum) == i)
                printf("%d and %d\n", i, sum);
            }
        }
    }
    
    int main(void) {
        int upperRange;
    
        printf("enter the value for upper range: ");
        if (scanf("%d", &upperRange) == 1) {
            printf("the amicable numbers between 2 and %d:\n", upperRange);
            amicableNumbers(upperRange);
        }
        return 0;
    }
    
    #包括
    int findSumofDivisor(int num){
    整数和=1,div,i;
    
    对于(i=2;i@chux是的,是的,先生。他对findSumofDevisor
    n=(int)sqrt((double)num)有问题;
    可能无法提供所需的整数平方根,因为
    sqrt()
    可能会有轻微的误差。建议只使用整数数学:
    (i=2;i
    findSumofDivisor
    *OT:无论visual studio会让程序员逍遥法外,来自
    main()
    的返回类型始终是
    int
    OT:调用任何
    scanf()
    函数族时,始终检查返回值(而不是参数值)为了确保操作成功。@snr,为什么我的sqrt函数无法承受?应该如何修复它,而不是将i*i与
    FindSumofDevisor一起使用(9)
    这段代码看起来像是在尝试求和
    1+3+3+9
    。我希望
    1+3+9
    。是的,这是我的第一种方法,但正如@chux所指出的,它可能会溢出。无论如何,+1是为了分享我的想法。另外,正如我在回答中提到的,
    如果(sum>i&&sum是的,可能,如果我们有机会克服存在微小可能性的问题,为什么我们要给它一个困难的时间?@snr:test
    sum@snr:纠正了
    i*i
    上的潜在溢出此函数中还有另一个错误:完美平方的平方根只能计算一次。
    for (i = 2; i < num/i; i++) {
      if (num%i == 0) {
    
    int findSumOfDivisors(int num) {
        int sum = 1, div, i;
    
        for (i = 2; i <= (div = num / i); i++) {
            if (num % i == 0) {
                sum += i;
                if (i == div)
                    break;
                sum += div;
            }
        }
        return sum;
    }
    
    void amicableNumbers(int n) {
        int sum, i;
    
        for (i = 2; i <= n; i++) {
            sum = findSumOfDivisors(i);
            if (sum > i && sum <= n && findSumOfDivisors(sum) == i)
                printf("%d and %d\n", i, sum);
            }
        }
    }
    
    #include <stdio.h>
    
    int findSumOfDivisors(int num) {
        int sum = 1, div, i;
    
        for (i = 2; i <= (div = num / i); i++) {
            if (num % i == 0) {
                sum += i;
                if (i == div)
                    break;
                sum += div;
            }
        }
        return sum;
    }
    
    void amicableNumbers(int n) {
        int sum, i;
    
        for (i = 2; i <= n; i++) {
            sum = findSumOfDivisors(i);
            if (sum > i && sum <= n && findSumOfDivisors(sum) == i)
                printf("%d and %d\n", i, sum);
            }
        }
    }
    
    int main(void) {
        int upperRange;
    
        printf("enter the value for upper range: ");
        if (scanf("%d", &upperRange) == 1) {
            printf("the amicable numbers between 2 and %d:\n", upperRange);
            amicableNumbers(upperRange);
        }
        return 0;
    }