целочисленный тип long и деление - PullRequest
0 голосов
/ 27 июня 2010

Я просто пишу процедуру для разложения целого числа без знака на простые числа. он будет работать нормально, если я определю тип данных как " int ", если я изменю его на " long ", результат будет неправильным Я не знаю почему.

Кстати, я использовал Win-TC в качестве компилятора.

Код как ниже:

#include "stdio.h"
#define True    0xff
#define False   0x00
char DividerIsPrime(unsigned long data);
void CheckIfDataCanBeExtracted(unsigned long data);
main()
{
    unsigned long data;
    printf("please input data:");
    scanf("%d",&data);
    printf("\n%d=",data);
    CheckIfDataCanBeExtracted(data);
//    printf("%d",sizeof(short));
    getch();
}

void CheckIfDataCanBeExtracted(unsigned long data)
{
    unsigned long divider,temp,data1;
    data1=data;
    for(divider=2;divider<=data;divider++)
    {
         temp=data1%divider;
         if(temp) {continue;  }
         if(DividerIsPrime(divider)) {
        data1 = data1/divider;
        printf("%d",divider);
        if(data1==1) break;

        else {printf("*");  divider--;}


      }
    }
    return;

}

/* Check if this number is a prime number */
char DividerIsPrime(unsigned long data)
{
    unsigned long divider;
    char    status=True;
    for(divider=2;divider<data;divider++)
    {
        if(data%divider) status=True;
        else status=False;
    }
    return status;
}

Спасибо за помощь Пола, я знаю, где это не так. % d следует заменить на% ld.

1 Ответ

1 голос
/ 27 июня 2010

Ваша функция DividerIsPrime, как написано в данный момент, имеет дефект, который по логике должен всегда возвращать True.

Причина этого в том, что статус меняется на каждой итерации. Даже если будет достигнуто status=False (число является составным, поскольку модуль делителя равен нулю для делителя), итерации будут продолжаться, и в каждом случае status=True будет достигнуто на последней итерации, когда divider == (данные - 1) .

Вы можете изменить это следующим образом:

/* Check if this number is a prime number */
char DividerIsPrime(unsigned long data)
{
    unsigned long divider;
    for(divider=2;divider<data;divider++)
    {
        if (0==(data % divider))
            return False;
    }

    return True;
}

Вы бы нашли это с помощью некоторого «модульного теста», такого как:

assert(DividerIsPrime(5));
assert(!DividerIsPrime(6));  /* This test would fail without corrected code. */

Очевидно, что есть гораздо более эффективные алгоритмы для "проверки простоты".

...