Reputation: 149
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
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
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