计算GCD时的浮点异常(核心转储)

vil*_*oob 3 c floating-point coredump

我正在编写一个程序,将分数降低到最低项.这是我的计划:

#include <stdio.h>
int main(){
    int m,x,n,gcd;
    printf("Enter a fraction: ");
    scanf("%d/%d",&n,&m);

    if(m==0)printf("Error");
    else
        for(;;){
           x=m%n;
           if(x==0){
              gcd=n;
              m/=gcd;
              n/=gcd;
              printf("In lowest terms: %d/%d",n,m);
            }else
                m=n;
                n=x;
         }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用Euclid的算法来计算GCD.执行时,它会报告

浮点异常(核心转储)

我的代码出了什么问题?

pad*_*ddy 5

您已成为阻止范围的受害者:

if(x==0){
    // ...
}else
    m=n;
    n=x;
Run Code Online (Sandbox Code Playgroud)

这将执行如下:

if(x==0){
    // ...
}else{
    m=n;
}
n=x;
Run Code Online (Sandbox Code Playgroud)

这意味着当x为零时,则n在循环结束时设置为零.当你再次来计算时m % n,你就遇到了问题.或者,如果由于某种原因,给出了一个数值没有崩溃您的程序,然后gcd = n将最终给你除以零,当你后来分裂mn通过gcd.

如果您希望多个语句成为else分支的一部分,则需要将它们括在大括号中,如下所示:

if(x==0){
    // ...
}else{
    m=n;
    n=x;
}
Run Code Online (Sandbox Code Playgroud)

事实上,即使你只有一个陈述,总是使用大括号是一种好习惯.在我的工作场所,这甚至是我们的编码标准,也是代码审查过程的一部分.