简体   繁体   English

不分零的浮点异常

[英]Floating point exception without division by zero

I compiled ths code, but it gives floating point exception on execution 我编译了代码,但它在执行时给出了浮点异常

#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;
 }

What should I do to resolve this problem? 我该怎么做才能解决这个问题?

What should I do to resolve this problem? 我该怎么做才能解决这个问题?

The first thing to address this problem would be to have a look at the hints your compiler is able to provide you. 解决这个问题的第一件事是查看编译器能够为您提供的提示。 That is, enable warnings ( -Wall ) and debugging symbols ( -g ): 也就是说,启用警告( -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]

There may be something wrong with the variable c in line 25, which is exactly the print statement: 第25行中的变量c可能有问题,这正是print语句:

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

Let's see what happens when we run it: 让我们看看运行时会发生什么:

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

Ah, well, it fails. 啊,好吧,它失败了。 But how did it crash? 但它是如何崩溃的呢? That's a use case for gdb : 这是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

Just at line 25. Suspicious. 就在第25行。可疑。 Let's examine the contents of the variables: 让我们检查一下变量的内容:

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

That variable c is indeed zero. 变量c确实为零。 But why is it causing a floating point exception when there are only integers? 但是,当只有整数时,它为什么会导致浮点异常? (Others have observed this before you.) As you can see in the debugger it's called an arithmetic exception (cf) : (其他人在您之前已经观察过这一点。)正如您在调试器中看到的那样,它被称为算术异常 (cf)

The SIGFPE signal reports a fatal arithmetic error. SIGFPE信号报告致命的算术错误。 Although the name is derived from “floating-point exception”, this signal actually covers all arithmetic errors, including division by zero and overflow. 尽管名称源自“浮点异常”,但该信号实际上涵盖了所有算术错误,包括除以零和溢出。

Let's see what valgrind tells us: 让我们看看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 identified an integer division by zero exactly at line 25. You should have an eye on that line (and the variables involved)! valgrind在第25行确定了一个零整数除法。你应该关注那一行(和所涉及的变量)!


Note that most IDEs (eg, Eclipse) have (some of) these tools directly integrated, which makes debugging really a charm. 请注意,大多数IDE(例如,Eclipse)都有(某些)这些工具直接集成,这使得调试真的很有魅力。

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

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

除了由沙菲克规定的问题, fibonacci(0)fibonacci(1)将失败,因为这没关系离开假设cint fibonacci(int)未初始化,因为它是在循环被设置为一个坏的n = 0n = 1因为将跳过while循环,因此您将返回一个未初始化的变量。

When passing 1 to fibonacci(int n) the method returns c without initializing it. 1传递给fibonacci(int n)该方法返回c而不初始化它。

Try this: 尝试这个:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM