0

I was creating a program to calculate the gcd of two numbers by using the Euclidian method but I got a floating point exception error. What should I do?

/*
 Euclidian Greatest Common Divisor Key Lemma 
 if gcd(a,b) = gcd(a',b) = gcd(b,a') Where a' = a % b
 Proof
 let a = a' + bq ... (1) , where q is some number
 if d is the gcd then b is divisible by d and also a is divisible by d
 then from the equation(1) we can see that a' is also divisible by d.
*/

#include<iostream>

using namespace std;

int euclidgcd(int a, int b)
{
    int c = a % b;
    if(b == 0)
    {
        return a;
    }
    else
    {
        return euclidgcd(b, c);
    }
}

int main()
{
   int a,b;
   std::cout << "give a and b where a > b" << '\n';
   std::cin >> a >> b;
   int d = euclidgcd(a, b);
   return 0;
}
dragosht
  • 3,237
  • 2
  • 23
  • 32
itachi99
  • 11
  • 1
  • 1
  • 2
    You should do this check `if (b == 0)` before `a % b` – DAle Jan 10 '18 at 08:26
  • 2
    ... because `% 0` is undefined behavior, which in your case throws. See [Can't Mod Zero?](https://stackoverflow.com/questions/7370154/cant-mod-zero) – Eran Jan 10 '18 at 08:28
  • I'm intrigued why/how you get a _floating_ point exception in code which solely uses integers. – Mike Vine Jan 10 '18 at 09:36
  • @MikeVine: He does not get a floating point exception. He gets a signal from integer divide-by-zero, whose *mnemonic* is (misleadingly) "floating-point exception". Note that in the answer, gdb gives a more correct description of "Arithmetic exception" – Ben Voigt Jan 11 '18 at 20:44

1 Answers1

0

It happens because the code divides by zero, which produces a SIGFPE. This can be easily seen when compiling the code with debug symbols and ASAN support (requires g++ or clang):

$ g++ -g -fsanitize=address -fsanitize=undefined -std=c++11  gcd.cpp; ./a.out 
give a and b where a > b
20
10
gcd.cpp:16:15: runtime error: division by zero
ASAN:DEADLYSIGNAL
=================================================================
==19101==ERROR: AddressSanitizer: FPE on unknown address 0x555b8634a4d8 (pc 0x555b8634a4d8 bp 0x7fffa1b82b00 sp 0x7fffa1b82ad0 T0)
    #0 0x555b8634a4d7 in euclidgcd(int, int) ./gcd.cpp:16
    #1 0x555b8634a4f6 in euclidgcd(int, int) ./gcd.cpp:23
    #2 0x555b8634a7fb in main ./gcd.cpp:32
    #3 0x7f8e99f071c0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x211c0)
    #4 0x555b8634a3a9 in _start (./a.out+0x13a9)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: FPE ./gcd.cpp:16 in euclidgcd(int, int)
==19101==ABORTING

The source code line in question (16) is this one:

int c = a % b;

To get some more insights, run the program from within a debugger (e.g. gdb):

$ gdb ./a.out 

(gdb) run
Starting program: /home/steemann/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
give a and b where a > b
20
10
gcd.cpp:16:15: runtime error: division by zero

Program received signal SIGFPE, Arithmetic exception.
0x00005555555554d8 in euclidgcd (a=10, b=0) at gcd.cpp:16
16      int c = a % b;

The program fails here because b has a value of 0 so a division by zero is carried out.

You can avoid this by testing for b to be non-zero before dividing or calculating the modulus. This is a good practice in general to avoid crashing programs.

stj
  • 9,037
  • 19
  • 33