我在hackerrank,我遇到了一个非常奇怪的问题。问题是“给你一个整数N.找到这个数字中的数字,准确地除以N(除以0作为余数)并显示它们的计数。对于N = 24,有2位数(2和4)。这两个数字都完全除以24.所以我们的答案是2.“。这是我的解决方案:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int t, count;
cin >> t;
for (int i = 0; i < t; i++) {
int n, copy;
cout << "i: " << i << " ";
cin >> n;
cout << "n: " << n << " ";
copy = n;
count = 0;
while (copy > 0) {
if (n % (copy % 10) == 0)
count++;
copy = copy/10;
}
cout << "\n" << count << "\n";
}
return 0;
}
t是测试用例的数量,n是要测试的数量。我可以毫无问题地输入我想要的任何数字。但是,如果我输入一个零到n的数字,我会得到一个浮点异常错误。该错误发生在第二个cout语句之前。其他数字工作正常(例如,1024给出错误,但1124很好)。我在hackerrank网站上运行了这段代码。有人可以解释一下发生了什么吗?
答案 0 :(得分:2)
当尝试执行非法算术运算时,通常会发生浮点异常。 (检查this)在你的例子中,你将最终做模数0,这是未定义的行为。大多数运行时都会因某种运行时错误而挽救。 以下是gdb在运行代码时给出的输出:
1 10
Program received signal SIGFPE, Arithmetic exception.
0x0000000000400920 in main () at a.cpp:21
21 if (n % (copy % 10) == 0)
尝试重新构建算法,以便最终不会这样做。
(我建议学习调试工具并通过它们运行代码来捕获这些问题)
关于为什么没有打印这行,这是因为cin和cout的大多数实现都是基于缓冲的(有关缓冲i / o的更多信息,请阅读this)。如果你添加了一个&#34; std :: endl&#34;在cout之后你可以看到输出来了。或者您可以使用std :: cerr输出调试信息。 std :: cerr对标准规定了更严格的要求,以便更加努力地进行冲洗。在您的情况下,可以刷新缓冲区之前应用程序终止。
答案 1 :(得分:1)
您不能将除以0除以0.尝试重新设计算法,以避免尝试执行该操作。也许检查copy % 10 == 0
然后跳过那个案例。 this stack exchange post
floating point exception
而不是divide by zero exception
的原因
答案 2 :(得分:1)
当您输入任何号码时,您的代码将正常运行。没有任何0位数。代码中的问题是你试图将数字除以0。
**if (n % (copy % 10) == 0)**
在此,当我们输入no为0作为数字时,(copy%10)的值变为0.因此它试图将n除以0,从而引发浮点异常错误。 像这样更改你的代码:
声明一个名为'r'的新变量。当我们将0作为数字时,这将阻止执行命令。因此程序运行得很好
while(copy!=0)
{`enter code here`
r=copy%10;
if(r!=0)
{
if(n % r==0)
count++;
}
copy=copy/10;
}
cout<<count<<endl;
答案 3 :(得分:0)
你不能用0来修改某些东西。检查以确保副本非零。