不分零的浮点异常

时间:2013-05-08 18:00:57

标签: c gcc

我编译了代码,但它在执行时给出了浮点异常

#include<stdio.h>
int fibonacci(int n)
{
  int a=0,b=1,c;
  while((n-1)>0)
  {
    c=a+b;
    a=b;
    b=c;
    n--;
  }
  return c;
}
int main()
{
  int t,a,b,c;
  scanf("%d",&t);
  while(t--)
  {
    scanf("%d%d",&a,&b);
    while(a--)
    {
      b=fibonacci(b);
    }
    printf("%d",(b%c));
   }
  return 0;
 }

我该怎么做才能解决这个问题?

4 个答案:

答案 0 :(得分:8)

  

我该怎么做才能解决这个问题?

解决此问题的第一件事是查看编译器能够为您提供的提示。也就是说,启用警告(-Wall)和调试符号(-g):

$ gcc test.c -Wall -g
test.c: In function ‘main’:
test.c:25:11: warning: ‘c’ may be used uninitialized in this function [-Wuninitialized]

第25行中的变量c可能有问题,这正是print语句:

printf("%d",(b%c));

让我们看看当我们运行它时会发生什么:

$ ./a.out
1
2
3
Floating point exception (core dumped)

啊,好吧,它失败了。但它是如何崩溃的呢?这是gdb的一个用例:

$ gdb ./a.out
GNU gdb (GDB) Fedora (7.5.1-37.fc18)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/moooeeeep/a.out...done.
(gdb) run
Starting program: /home/moooeeeep/a.out 
1
2
3

Program received signal SIGFPE, Arithmetic exception.
0x0000000000400640 in main () at test.c:25
25      printf("%d",(b%c));
Missing separate debuginfos, use: debuginfo-install glibc-2.16-30.fc18.x86_64

就在第25行。可疑。让我们检查一下变量的内容:

(gdb) print b
$1 = 1
(gdb) print c
$2 = 0

变量c确实为零。但是,当只有整数时,它为什么会导致浮点异常? (Others have observed this before you.)正如您在调试器中看到的那样,它被称为算术异常 (c.f.)

  

SIGFPE信号报告致命的算术错误。虽然名称源自“浮点异常”,但该信号实际上涵盖了所有算术错误,包括除以零和溢出。

让我们看看valgrind告诉我们的内容:

$ valgrind ./a.out
==3113== Memcheck, a memory error detector
==3113== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3113== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3113== Command: ./a.out
==3113== 
1
2
3
==3113== 
==3113== Process terminating with default action of signal 8 (SIGFPE)
==3113==  Integer divide by zero at address 0x403E58A5B
==3113==    at 0x400640: main (test.c:25)
==3113== 
==3113== HEAP SUMMARY:
==3113==     in use at exit: 0 bytes in 0 blocks
==3113==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==3113== 
==3113== All heap blocks were freed -- no leaks are possible
==3113== 
==3113== For counts of detected and suppressed errors, rerun with: -v
==3113== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Floating point exception (core dumped)

valgrind在第25行确定了一个整数除以零。您应该关注该行(以及所涉及的变量)!


请注意,大多数IDE(例如Eclipse)都有(某些)这些工具直接集成,这使得调试真的很有魅力。

答案 1 :(得分:3)

你没有初始化c,所以你正在模拟一些未定义的数字,可能是0

printf("%d",(b%c));

答案 2 :(得分:2)

除了Shafik所述的问题之外,fibonacci(0)fibonacci(1)会失败,因为假设可以将c中的int fibonacci(int)保留为未初始化,因为它已被设置为n = 0n = 1的循环不好,因为while循环将被跳过,因此您将返回一个未初始化的变量。

答案 3 :(得分:1)

1传递给fibonacci(int n)时,该方法会在不初始化的情况下返回c。

试试这个:

int fibonacci(int n)
{
  if(n==0 || n==1)
    return n;

  int a=0,b=1,c;
  while((n-1)>0)
  {
    c=a+b;
    a=b;
    b=c;
    n--;
  }
  return c;
}