Alex D
Alex D

Reputation: 149

Why do I get floating point exception 8?

For my Intro. to programming exam review I was asked to write a program which uses a function to calculate the gcd of a set of numbers. I wrote the following code, which sometimes seems to work fine, but others returns Floating Point Exception 8. I was hoping someone could shed some light.

I complied it using clang gcd.c -o gcd on the mac terminal using macOS High Sierra and the numbers that return the FP error were 5372 18960 -230048 1185 16486

This is the code:

#include <stdio.h>
#include <stdlib.h>

int gcd(int a, int b){
    if((a==0) || (b==0)){
        return 0;
    }else{
        if( a % b == 0 ){
            return b;
        }else{
            if ( b % a == 0 ){
                return a;
            }
        }
    }
    while( (a != 0) && (b != 0) ){
        if (abs(a)>abs(b)){
            a = abs(a) % abs(b);
        }
        if(b>a){
            b = abs(b) % abs(a);
        }
    }
    if (a == 0){
        return b;
    }else{
        return a;
        }
}

int main(void){
    int n;
    printf("Please enter the number of integers in your array:\n");
    scanf("%d", &n);

    int a[n];

    printf("Please enter the numbers in your arrray:\n");

    for (int i = 0; i < n; ++i){
        scanf("%d", &a[i]);
    }

    for (int i = 0; i < (n-1); ++i){
            a[i] = gcd(a[i], a[i+1]); 
    }

    printf("The gcd of the %d numbers is %d .\n", n, a[n-2]);

    return 0;
}

Upvotes: 0

Views: 1427

Answers (2)

asio_guy
asio_guy

Reputation: 3767

first impression in the while loop below

while( (a != 0) && (b != 0) ){
    if (abs(a)>abs(b)){
        a = abs(a) % abs(b); // value of a is altered and reused 
    }
    if(b>a){
        b = abs(b) % abs(a);  // here <-- and could very well be a 0
    }
}

on a completely different note your could remove else {} blocks, if you could take a moment and see that else blocks are not really adding any value because there is a return in if

int gcd(int a, int b){

    /** sanity checks */
    if((a==0) || (b==0))
        return 0;

    /* few more obvious checks */
     if( a % b == 0 )
        return b;
     if( b % a == 0 )
        return a;

    /* Real Logic */
     while( (a != 0) && (b != 0) ){
        if (abs(a)>abs(b)){
            a = abs(a) % abs(b);
        }
        else if(abs(b) > abs(a) ){
            b = abs(b) % abs(a);
        }
    }

    /* Final results */
    return (a == 0) ? b : a;
}

Upvotes: 2

vinayawsm
vinayawsm

Reputation: 865

Looks like couple of mistakes in your code for finding GCD.

You should update the value of a[i+1] in your for loop instead of a[i]. And the GCD will be a[n-1]th element after this change. As you iterate over the loop a[i] and a[i+1] will be original (input) values in your case. So if everything else works fine, your result will be GCD of last two elements of the array (a[n-2], a[n-1]).

for (int i = 0; i < (n-1); ++i) {
    a[i+1] = gcd(a[i], a[i+1]); 
}

In the while loop of gcd(), you need to make the following changes. Check for a==b conditionality and change the two if conditions to if-else conditions. In case b is a factor of a, a becomes 0 in your first if condition. Then in the second condition, you are doing % 0 which is throwing the error.

while( (a != 0) && (b != 0) ){
    if (abs(a)>=abs(b){
        a = abs(a) % abs(b);
    }
    else if(abs(b)>abs(a)){
        b = abs(b) % abs(a);
    }
}

Upvotes: 2

Related Questions