在不同编译器上产生不同输出的代码
我在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与海湾合作委员会上) - 正确
5
111 101 101 101 1
为避免将结果小于数学结果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;
};
再进我的解决方案,我带着一个团队,去您在您的文章中引用的网站(并不需要这样做)。我提交了你发布的原始代码,是的,你得到的错误。因此,在我在主要评论部分中链接到的SO评论中,由于浮点和截断问题,pow
函数确实会导致问题。
为了解决这个问题,你可以做几件事情,主要是给出的其他答案。不过,我会给我的解决方案:
unsigned long powTable[] = { 1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000 };
//...
return ((digit-1)*powTable[tens]+res);
,而不是调用的pow
功能,具有10个权力简单的查找表声明,然后tens
被用作索引表。
嗯,我看不出这是对'int(0.5 + pow(10,几十))'的改进,无论是只需要一次的代码还是(特别是)更一般的可重用代码? –
这是一个不使用'pow',而是使用查找表的替代解决方案。从未声称这是“更好”,只是一种选择。 – PaulMcKenzie
'POW(10,十位)' - 如果你有整数指数不要使用'pow'。 [不保证pow会给你正确的结果](http://stackoverflow.com/questions/25678481/why-pown-2-return-24-when-n-5/25678721#25678721)。 – PaulMcKenzie
我不认为它与架构或编译器有关。测试数字是否大于零时,请使用完整的条件。即使用'if(num> 0)'而不是'if(num)'。不确定这是否是问题 – smac89
*我没有看到任何可以在不同编译器上产生未定义行为的语句* - 但是您确实有产生浮点值的语句('pow()'),因此您的程序不是保证产生相同的结果。 – PaulMcKenzie