Runtime Error - SIGFPE - c++

I HAVE THE FOLLOWING CODE for hackerearth competetion and WRITTEN IN C++ (g++ 4.8.4)
it is giving SIGFPE on runtime
I am just done with it
plz tell how tofix it
#include<iostream>
using namespace std;
int factorial(int n);
int main()
{
int n , k ,totitem , totways=0 , har1,har2, ansh=1;
int res;
cin>>n>>k;
totitem = (n/k);
ansh=factorial(n);
if(totitem>0)
for(int i=0;i<=totitem*k;i+=k)
{
har1=factorial(i);
har2=factorial(n-i);
totways+=(ansh/(har1*har2));
}
cout<<totways;
return 0;
}
int factorial(int n)
{
if(n>1)
return n*factorial(n-1);
else
// if(n==0 || n==1)
return 1;
}

It is usually division by zero error.
There are two divide statements in your code.
1:
totitem = (n/k);
where you don't sanitise your input.
2:
har1=factorial(i);
har2=factorial(n-i);
totways+=(ansh/(har1*har2));
And this will fail if any of the har parameters equals to zero.
The most probable cause of the problem is that you are using 32-bit signed integers (int) to do factorial calculations, which are limited to factorial of 12! Trying to do factorial with larger numbers will cause overflow and thus incorrect result and eventually a zero value, that caused your runtime error.

Related

Recursive call getting stuck

#include <bits/stdc++.h>
using namespace std;
int gcd(long long int a, long long int b){
if(a||b==0){
return 0;
}
else if(b==a){
return a;
}
else if(a>b){
return gcd(a-b,b);
}
else{
return gcd(a,b-a);
}
}
int lcm(long long int a,long long int b){
return a*b/(gcd(a,b));
}
int main(){
long long int answer=1;
for (int i = 2; i<=20; i++) {
answer=lcm(i,answer);
cout<<answer;
}
cout<<answer;
return 0;
}
i wrote this code for problem 5 in project euler. however the output screen is showing nothing and is getting hanged. i put a few debugging cout statements and i understood that in the main function the it is entering the loop but it is not continuing the excution after the call for lcm.
the program is to find the lcm of numbers from 1 to 20. i used the formula llcm= a*b/gcd(a,b). where in gcd also i used the recursive euclidian algorithm. i am not able to trace out the reason for this bug . could anyone help pls.
also if there any suggestions regarding my coding style (indentation, type casting, variable names, algorithm or anything) please point it out. i am beginner so i do not know much regarding c++ and programming styles.
Your program is becoming stuck because of this line:
if (a || b == 0) {
The == operator has higher precedence than ||, so the condition is in fact the same as:
if (a || (b == 0)) {
Which in C(++) is the same as:
if ((a != 0) || (b == 0)) {
That is, if a is non-zero OR b is zero. a will be non-zero straight away, hence your program will always try to divide by zero, which causes problems. I am not sure where you found this version of the algorithm, a cursory search results in a much simpler variant:
int gcd(int a, int b) {
if (b == 0) {
return a;
} else {
return gcd(b, (a % b));
}
}
As for the second part of your question, there are many little (stylistic) issues in your code that I would change. Inconsistent spacing, unnecessary use of long long int (an int would do just fine here) … But for these, I recommend the codereview StackExchange.

Why does my code for SPOJ GCD2 error on SPOJ?

Following is code for SPOJ GCD2. It's running well on my machine and Ideone, but getting runtime error (SIGFPE) on SPOJ. I have checked all the test cases also available at spojtoolkit.com.
I am unable to figure out why this code is showing runtime error (SIGFPE) on spoj. SIGFPE means Erroneous arithmetic operation.
Why is this code showing runtime error on SPOJ?
#include <bits/stdc++.h>
using namespace std;
int gcd(int x,int a)
{
if(a==0)
return x;
else
return gcd(a, x%a);
}
int getmod(string b,int a)
{
int n=b.size();
int d;
d= (b[0]-'0') % a;
for(int i=1; i!=n; i++)
{
d=d*10;
d=d + (b[i]-'0');
d= d % a;
}
return d;
}
int main()
{
int tc;
cin >> tc;
int a;
string b;
while(tc--)
{
cin >>a>>b;
int x=getmod(b,a);
cout << gcd(x,a)<<endl;
}
return 0;
}
int getmod(string b,int a)
{
int n=b.size();
int d;
d= (b[0]-'0') % a;
If a = 0, this will error, because % 0 is like dividing by zero. a can be zero according to the problem statement.
The error covers division by zero:
The SIGFPE signal reports a fatal arithmetic error. Although the name is derived from “floating-point exception”, this signal actually covers all arithmetic errors, including division by zero and overflow. If a program stores integer data in a location which is then used in a floating-point operation, this often causes an “invalid operation” exception, because the processor cannot recognize the data as a floating-point number.
You can fix it by checking if a == 0 and simply returning b as the answer in that case. Else call your current function as is.

What is wrong with this recursive factorial implementation?

I compiled and run in my computer, and it executes correctly. I tried IDEONE, and I got a successful answer.
But when I submit it in SPOJ, I'm getting a wrong answer. Is something wrong in this implementation?
#include <iostream>
#include <cstdio>
using namespace std;
int factorial(int n) {
if (n <= 1)
return 1;
return n * factorial(n - 1);
}
int main() {
int t;
int n;
cout << "";
cin >> t;
for (int i = 0; i < t; i++) {
cout << "";
cin >> n;
printf("%d\n", factorial(n));
}
return 0;
}
The problem with the above code is due to the finite space we can use to store the value of an int. On a 32-bit machine, int's have 32 bits (value 0 or 1), which means that the maximum value an unsigned int can have is (2^31 - 1) and the maximum value an int can have is (2^30 - 1) (since it needs one bit to denote whether it is positive or negative, while the unsigned int is always positive and can devote that bit to just regular value).
Now, that aside, you should look into ways of storing the value of a very large number in a different data structure! Maybe an array would be a good choice...
Just to brainstorm, imagine creating an int bigInteger[100] (that should be large enough to hold 100!). To multiply two of your numbers, you could then implement a bitMultiplication(int bitNum[], int num) function that would take in your array by reference and perform bitwise multiplication (see the following post for details: Multiplying using Bitwise Operators).
Use that bitMulitiplication(int bitNum[], int num) instead of the regular multiplication in your recursive factorial function, and you should have a function that works on large n!

How to implement N choose R?

I just wrote this code :
#include <iostream>
using namespace std;
unsigned long long int choose(unsigned long long int k, unsigned long long int n)
{
if (k==n or k==0)
{
return 1;
}
else
{
return (choose(n-1,k-1)+choose(n-1,k));
}
}
int main(){
cout << choose(3, 6);
}
but I got Run-Time Error, I think my problem is in my variables, I did debugging but I couldn't find the answer, why I got run time error?
Since your variables are unsigned, substracting 1 from them when they're already 0 will make them roll over to the max value.
When n reaches 0 and you then call choose(n-1,k), this'll happen and that's the source of the issue (stackoverflow).

Calculate sin(x) as the form of series in c++

We know that
sin(x)=x-x^3/3!+x^5/5!-x^7/7!+x^9/9! and so on. I have written this code:
#include <iostream>
#include <math.h>
using namespace std;
const int m=19;
int factorial(int n) {
if (n==0){ return 1;}
return n*factorial(n-1);
}
int main() {
float x;
cin >> x;
float sum=0;
int k=1;
for (int i=1;i<=m;i+=2) {
sum+=(k*(powf(x,i)/factorial(i)));
k=k*(-1);
}
cout<<"series sum is equal :"<<sum<<endl;
return 0;
}
One problem is that when I enter x=3 it gives me -10.9136, but I know that values range of sin(x) is [-1, 1] what is problem? Please help me.
The problem is that you're running out of precision due to destructive cancellation.
You have an alternating series where some of the terms get very large. But those terms cancel each other out to a small result. Since float has limited precision, your round off error is larger than your final value.
You can "reduce" the problem by using double-precision. But it won't go away. Standard implementations of sin/cos involve taking the modulo of the argument by 2 pi to make it small.
EDIT :
I found the other problem. You have an integer overflow in your factorial function when i = 19.