我正在创建一个程序来使用Euclidian方法计算两个数字的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;
}
答案 0 :(得分: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
为非零来避免这种情况。一般来说,这是一种很好的做法,可以避免程序崩溃。