Reputation: 665
I have no idea why g++ doesn't like my code. It ran fine in java. Any insights would be greatly appreciated.
#include<iostream>
using namespace std;
bool isPrime(long number);
int main(){
const long number = 600851475143;
long max = 0;
for(long i= 0; i*i <= number; i++)
if(number % i == 0 && isPrime(i))
max = i;
cout<< max << endl;
return 0;
}
bool isPrime(long number){
if(number <= 1) return false;
if(number == 2) return true;
if(number % 2 == 0) return false;
for(long i= 3; i*i <= number; i+=2)
if(number % i == 0)
return false;
return true;
}
Upvotes: 20
Views: 61782
Reputation: 34703
For me, this bug came up when checking for integer overflow when doing a product:
#define INT_MIN -2147483648 // -2^31
#define INT_MAX 2147483647 // 2^31-1
int out=-1, x=-5;
if ((out > 0 && (x > INT_MAX/out || x < INT_MIN/out)) ||
(out < 0 && (x < INT_MAX/out || x > INT_MIN/out))) {
// what to do for overflow
} else {
out *= x;
}
The issue is that because abs(INT_MIN) > abs(INT_MAX)
, exactly when out=-1
, the condition INT_MIN/out
was causing an overflow of int
(because of 0
, there's not enough room to fit INT_MAX+1
in int
). I added a new condition to fix the floating point issue: out == -1 && (x > INT_MAX || x <= INT_MIN)
Upvotes: 0
Reputation: 45410
const long number = 600851475143;
There is overflow, long can't hold that big number.
see this link
LONG_MAX is 2147483647
try:
const unsigned long long number = 600851475143;
unsigned long longmax = 0;
Edit:
You can't % against 0, i
starts from 0
for(long i= 0; i*i <= number; i++)
^^
{
if(number % i == 0 && isPrime(i))
^^^
{
max = i;
cout<< max << endl;
}
}
Minor change to a working version:
bool isPrime(unsigned long long number);
int main(){
const unsigned long long number = 600851475143;
unsigned long long max = 0;
for(long i = 1; i*i <= number; i++)
{
if(number % i == 0 && isPrime(i))
{
max = i;
cout<< max << endl;
}
}
return 0;
}
bool isPrime(unsigned long long number)
{
if(number <= 1) return false;
if(number == 2) return true;
if(number % 2 == 0) return false;
for(unsigned long long i= 3; i*i <= number; i+=2)
{
if(number % i == 0)
{
return false;
}
}
return true;
}
Upvotes: 23
Reputation: 21317
I don't see a floating point anywhere, but if I had to guess it's because it's due to overflow. Use unsigned long long
or long long
instead of regular long
.
sizeof(long)
on some compilers has evaluated to 4, similar to sizeof(int)
, which means that the limit of long
is 2147483647. long long
is required by the C++ standard to be at least 64-bits, double that of long
and int
, which has a signed maximum of 9223372036854775807.
The error stems from your code: You're doing modulus by zero, which is wrong.
Consider doing this instead:
#include <iostream>
using namespace std;
bool isPrime(unsigned long long number);
int main(){
const unsigned long long number = 600851475143;
unsigned long long max = 0;
for(unsigned long long i= 1; i*i <= number; i++)
if(number % i == 0 && isPrime(i))
max = i;
cout<< max << endl;
return 0;
}
bool isPrime(unsigned long long number) {
if(number <= 1) return false;
if(number == 2) return true;
if(number % 2 == 0) return false;
for(unsigned long long i= 3; i*i <= number; i+=2)
if(number % i == 0)
return false;
return true;
}
Notice how i = 0
was changed to i = 1
Upvotes: 2