I want to find all the exact divisors of a number. Currently I have this:
{
int n;
int i=2;
scanf("%d",&n);
while(i<=n/2)
{
if(n%i==0)
printf("%d,",i);
i++;
}
getch();
}
Is there any way to improve it?
The most basic method for computing divisors is exhaustive trial division. If we want to find the positive divisors for an integer n, we just take the integers 1, 2, 3, . . . , n, divide n by each, and those that divide evenly make up the set of positive divisors for n.
A divisor, or factor, is a number that divides evenly into a larger integer. It is easy to determine how many divisors a small integer (such as 6) has by simply listing out all the different ways you can multiply two numbers together to get to that integer.
First, your code should have the condition of i <= n/2
, otherwise it can miss one of the factors, for example 6 will not be printed if n=12.
Run the loop to the square root of the number (ie. i <= sqrt(n)
) and print both i
and n/i
(both will be multiples of n).
{ int n; int i=2; scanf("%d",&n); while(i <= sqrt(n)) { if(n%i==0) { printf("%d,",i); if (i != (n / i)) { printf("%d,",n/i); } } i++; } getch(); }
Note :
i*i == n
as suggested by @chepner.Finding all divisors by using "finding all prime factors" in C (faster) and up to 18 digits.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
unsigned int FindDivisors(unsigned long long divisors[], unsigned long long N) {
unsigned int lastdiv = 0;
divisors[lastdiv++] = 1;
unsigned long long powerfactor = 1;
unsigned long long number = N;
while ((number & 1) == 0) {
powerfactor <<= 1;
divisors[lastdiv++] = powerfactor;
number >>= 1;
}
unsigned long long factor = 3; unsigned long long upto = lastdiv;
powerfactor = 1;
while (factor * factor <= number) {
if (number % factor == 0) {
powerfactor *= factor;
for (unsigned int i = 0; i < upto; i++)
divisors[lastdiv++] = divisors[i] * powerfactor;
number /= factor;
}
else {
factor += 2; upto = lastdiv;
powerfactor = 1;
}
}
if (number > 1) {
if (number != factor) {
upto = lastdiv;
powerfactor = 1;
}
powerfactor *= number;
for (unsigned int i = 0; i < upto; i++)
divisors[lastdiv++] = divisors[i] * powerfactor;
}
return lastdiv;
}
int cmp(const void *a, const void *b) {
if( *(long long*)a-*(long long*)b < 0 ) return -1;
if( *(long long*)a-*(long long*)b > 0 ) return 1;
return 0;
}
int main(int argc, char *argv[]) {
unsigned long long N = 2;
unsigned int Ndigit = 1;
if (argc > 1) {
N = strtoull(argv[1], NULL, 10);
Ndigit = strlen(argv[1]);
}
unsigned int maxdiv[] = {1, 4, 12, 32, 64, 128, 240, 448, 768, 1344,
2304, 4032, 6720, 10752, 17280, 26880, 41472, 64512, 103680};
unsigned long long divisors[maxdiv[Ndigit]];
unsigned int size = FindDivisors(divisors, N);
printf("Number of divisors = %u\n", size);
qsort(divisors, size, sizeof(unsigned long long), cmp);
for (unsigned int i = 0; i < size; i++)
printf("%llu ", divisors[i]);
printf("\n");
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With