I have started solving the problems of http://projecteuler.net/, but I can't seem to work out problem # 3. I think it will be fairly easy for the most of you.
#include <stdio.h>
#include <stdbool.h> //This is to bring in the define of true
#include <math.h> //This is to bring in the define of sqrt()
int LargestFactor (long number);
bool IsItPrime (int number);
int main (int argc, const char * argv[]) {
long number;
number = 6008514751开发者_如何学C43;
printf("The largest prime factor of %ld is %d.", number, LargestFactor(number));
}
int LargestFactor (long number) {
int divider,i=1;
bool foundIt=false;
while (foundIt == false) {
i++;
if (number % i == 0 && IsItPrime(number/i)) {
divider = number / i;
foundIt=true;
}
}
return divider;
}
bool IsItPrime (int number) {
int i=1;
bool isPrime=true;
while (i<sqrt(number) && isPrime == true) {
i++;
if (number % i == 0) {
isPrime=false;
}
}
return isPrime;
}
also I get this result:
The largest prime factor of 600851475143 is -127237759.
The problem is that there is a maximum value that the long type can hold, and when you try to store a number larger than the max that type you can hold you may get negative results because of the 2's compliment system.
Refer to this page: http://en.wikipedia.org/wiki/Limits.h
Which will show you the guaranteed minimum values the data types will hold.
So, you should declare number in this way: long long int number = 600851475143LL
So that it will be large enough to hold the number.
The number 600851475143
is greater than INT_MAX
when the integer is represented with 32-bit (which is the case on most common platform). You should probably change all your variables and return values from int
to uint64_t
(from stdint.h
). Moreover, you should change your immediate value to 600851475143LL
so that it is not casted to int
by the compiler.
Like others said, you need to use 64 bit integers.
You should also use %lld
in your printf
.
And ideally avoid using sqrt and libm by changing your while statement to:
while ((i*i)<number && isPrime == true) {
You need to look at your integral type sizes. Your original number is about 600 billion, which won't fit in a 32-bit integer. What happens with signed overflow is technically undefined, but most modern systems will make a stab at modular arithmetic for you.
On some systems, long
is 32 bits, and 64 bits (which will work for your use here). Assuming you have some C99 on your platform, long long
is at least 64 bits. Use it.
Be careful of intermediate results also. You're using int
in some of your processing (i
and divider
from LargestFactor
, and you're even passing an int
to IsItPrime
). Use long long
for all variables involved in the calculation, or you'll be truncating part of your values sometimes.
And, as Sylvain Defresne suggested, put LL
at the end of your numeric literal. It's at least clearer that way.
If your number has large prime factors, you're going to have problems with your algorithm, since it will seem to take forever, but that would be a separate question.
Instead only long..
you can also use long long
and double long
.
so that you get the answer in positive sign.
精彩评论