0

我正在创建一个程序来使用欧几里得方法计算两个数字的 gcd,但我得到了一个浮点异常错误。我应该怎么办?

/*
 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;
}
4

1 回答 1

0

发生这种情况是因为代码除以零,这会产生 SIGFPE。在使用调试符号和 ASAN 支持(需要 g++ 或 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

有问题的源代码行(16)是这一行:

int c = a % b;

要获得更多见解,请从调试器(例如 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;

程序在这里失败,因为b它的值是0除以零。

b您可以通过在除或计算模数之前测试非零来避免这种情况。通常,这是避免程序崩溃的好习惯。

于 2018-01-11T20:35:22.037 回答