代码在不同的编译器上产生不同的输出

时间:2016-07-24 21:07:58

标签: c++

我在Codeforces上解决Quasi-Binary问题(无关紧要),这是我的submission。这是我制作的代码:

#include <iostream>
#include <cmath>

using namespace std;

int quasi_binary(int num, int tens)
{
    int res,digit;

    if(num == 0)
    {
        return 0;
    }

    digit = num%10;
    num = num/10;

    res = quasi_binary(num, tens+1);

    if(digit)
    {
        cout << 1;
        return ((digit-1)*pow(10,tens)+res);
    }
    else
    {
        cout << 0;
        return res;
    }
}

int main()
{
    int n,k=-1,temp,digit;
    cin >> n;

    //this loop calculates the value of k,as it needs to be printed first
    temp=n;
    while(temp)
    {
        digit = temp%10;
        temp = temp/10;

        if(digit>k)
            k=digit;
    }
    cout << k << endl;

    //print those k quasi-numbers
    while(n)
    {
        n = quasi_binary(n,0);
        cout << " ";
    }
    return 0;
} 

我没有看到任何可能在不同编译器上产生未定义行为的语句。我在适当的地方使用了适当的括号,以避免歧义。仍然得到未定义的行为。任何人都可以帮助找到产生未定义行为的语句/指令。

输入

415

输出(在线判断) - 不正确

5
111 101 101 11 11 11 11 11 11 11 11 11 

输出(在我的64位PC上使用gcc) - 正确

5
111 101 101 101 1

2 个答案:

答案 0 :(得分:5)

要避免向下舍入到比数学结果小1,请将pow(10, tens)替换为int( 0.5 + pow( 10, tens ) )

或者,编写自己的整数幂函数。

E.g。

using Int_noneg = int;     // "Not negative"

auto int_pow( Int_noneg const x, Int_noneg const exponent )
    -> int
{
    Int_noneg   reverse_bits = 0;
    Int_noneg   n_exponent_bits = 0;
    for( Int_noneg i = exponent; i != 0; i /= 2 )
    {
        reverse_bits = 2*reverse_bits + i%2;
        ++n_exponent_bits;
    }

    Int_noneg   result = 1;
    for( Int_noneg i = 0; i < n_exponent_bits; ++i, reverse_bits /= 2 )
    {
        result *= result;
        if( reverse_bits % 2 != 0 ) { result *= x; }
    }
    return result;
};

答案 1 :(得分:0)

在进入我的解决方案之前,我为团队拿了一个,然后去了你在帖子中引用的网站(不需要这样做)。我提交了您发布的原始代码,是的,您收到了错误消息。因此,在我在主要评论部分中链接的SO注释中,pow函数确实会因浮点和截断问题而导致问题。

为了解决这个问题,你可以做一些事情,主要在给出的其他答案中概述。但我会给出我的解决方案:

unsigned long powTable[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 
                             10000000, 100000000, 1000000000 };

//...
return ((digit-1)*powTable[tens]+res);

不是调用pow函数,而是声明一个功能为10的简单查找表,然后将tens用作表的索引。

Live Example