Josh Horowitz
Josh Horowitz

Reputation: 665

Getting the error floating point exception: 8

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

Answers (3)

MichaelChirico
MichaelChirico

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

billz
billz

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

Rapptz
Rapptz

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

Related Questions