【问题标题】:Floating point exception: 8浮点异常:8
【发布时间】:2017-06-07 05:06:25
【问题描述】:

为什么会出现错误:Floating point exception: 8

#include<stdio.h>
//grid problem
int fact(int n)
{

    int i,f=1;
    if(n==0)
        return 1;
    for(i=1;i<=n;i++)
        f*=i;
    return f;
}

int uniquePaths(int A, int B) {
    float m;
    m=fact(A+B-2)/(fact(A-1)*fact(B-1));
    return m;
}

int main(int argc, char const *argv[])
{
    int a,b;
    //aXb grid
    scanf("%d%d",&a,&b);
    printf("%d\n",uniquePaths(a,b) );
    return 0;
}

【问题讨论】:

  • 显示您的输入。
  • scanf("%d %d", &amp;a, &amp;b); 注意空格。
  • 估计是计算大阶乘时发生了溢出。所以除以 0 发生。
  • @Shiva:格式字符串中的空格无关紧要; %d 无论如何都会跳过前导空格。参数之间的空格纯粹是装饰性的。
  • 对于 32 位 int,任何总和超过 64 的输入 a,b 可能会溢出 fact(A-1)*fact(B-1),UB 结果为 0。然后 int/int 0 导致“浮点异常”。发布使用的输入将有助于澄清这篇文章。

标签: c


【解决方案1】:

如果您使用函数 assert 添加前置条件和后置条件,您可以确保参数和函数结果具有合理的值:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

//grid problem
int fact(int n)
{
    assert(n >= 0);
    int i, f = 1;
    if (n == 0) {
        return 1;
    }
    for (i = 1; i <= n; i++) {
        f *= i;
    }
    assert(f >= 1);
    return f;
}


int uniquePaths(int A, int B)
{
    assert(A >= 1);
    assert(B >= 1);
    int q = fact(A - 1) * fact(B - 1);
    assert(q > 0);
    int m = fact(A + B - 2) / q;
    assert(m >= 1);
    return m;
}


int main(int argc, char const *argv[])
{
    int a, b;
    //aXb grid
    int n = scanf("%d%d", &a, &b);
    if (n == 2) {
        printf("%d\n", uniquePaths(a, b));
    } else {
        fprintf(stderr, "invalid input\n");
        exit(1);
    }
    return 0;
}

例如,在我的机器上,使用输入 10 10 运行上面的程序会导致

t: t.c:16: int fact(int): Assertion `f >= 1' failed.
Aborted

(但我不知道为什么会出现浮点异常。)

【讨论】:

  • 真正需要的测试是产品(fact(A - 1) * fact(B - 1))是否为零。
  • @chux 阶乘总是正的,后置条件也断言是这样。
  • 使用int 商,分配给floatINT_MAX 附近的结果可以得到一个四舍五入的值INT_MAX+1。尽管这通过了assert(m &gt;= 1);,但转换回intUB,其中包括返回值0。更令人担忧的是,由于int 溢出,乘积fact(A - 1) * fact(B - 1) 可能仍为0。 int OF 的结果是 UB,潜在结果是 0。因此,建议在 int 除潜在 0 之前使用 assert(product != 0),这通常表明自己是“浮点异常”。
  • @chux 我错过了 int 到 float 的转换。我已将 float 更改为 int 并为分母添加了一个零断言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 2014-12-05
  • 2011-01-14
  • 1970-01-01
相关资源
最近更新 更多