What is wrong with this recursive factorial implementation? - c++

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!

Related

Last Digit of the Sum of Fibonacci Numbers. Unable to get exact answer

#include<iostream>
#include<vector>
#include<cstdlib>
#include <cassert>
using namespace std;
long long int LastDigitofSumofFibonacci(int n){long long int first=0;
long long int second=1;
long long int fibOfn;
long long int sum=1;
vector<long long int> V;
V.push_back(first);
V.push_back(second);
if(n==0) return first;
else if(n==1) return second;
else{
for(int i=2;i<60;i++){
fibOfn=first+second;
first=second;
second=fibOfn;
sum=sum+fibOfn;
//cout<<"i "<<i<<" fibOfn "<<fibOfn<<" fibOfnlastdigit "<<fibOfnlastdigit<<" first "<<first<<" second "<<second<<" sum "<<sum;
//cout<<endl;
sum=sum%10;
V.push_back(sum);
}
}
//for(auto element:V)
//cout<<element<<" ";
//cout<<endl;
//cout<<(n)%60<<endl;
return V[(n)%60];
}
int main(){
int n;
cin>>n;
long long int Base=LastDigitofSumofFibonacci(n);
cout<<Base<<endl;
}
In this I am trying to calculate the the last digit of Fibonacci series. I know and also read from net that last digit follow pattern of 60(0-59). from that concept wise I think my code is OK. but still I am unable to get the correct answers for large digit number.
I cleaned up the code a bit and fixed the issue with second not being computed % 10.
Since only the last digit is relevant all variables can be just int, no need for long long int to store a single digit. It would actually save ram to use uint8_t as type for the cache, but 60 bytes or 240 bytes isn't going to make a difference here.
The result repeats every 60 steps, which is the basis for the algorithm. But why compute this every time the function gets called? So lets make a static array so the computation only happens once. Lets go one step further with constinit and compute it at compile time.
As last change I made the argument to LastDigitofSumofFibonacci unsigned int. Unless you want to extend the fibonacci series backwards into the negative and extend the algorithm. unsigned int generates better code for n % 60.
#include <iostream>
#include <array>
int LastDigitofSumofFibonacci(unsigned int n) {
// The last digit of `fib(n)` and their sum repeats every 60 steps.
// https://en.wikipedia.org/wiki/Pisano_period
// Compute the first 60 values as lookup table at compile time.
static constinit std::array<int, 60> cache = []() {
int first = 0, second = 1;
std::array<int, 60> a{0, 1};
for (int i = 2; i < 60; i++) {
int t = first + second;
first = second;
second = t % 10;
a[i] = (a[i - 1] + t) % 10;
}
return a;
}();
// and now just look up the answer at run time.
return cache[n % 60];
}
int main(){
int n;
std::cin >> n;
std::cout << LastDigitofSumofFibonacci(n) << std::endl;
}
Somehow the code got a lot shorter just from eliminating some overhead here and there.

Problem when i used some large large value i get wrong output with my function

So I'm new to stackoverflow and coding I was learning about functions in c++ and how the stack frame works etc..
in that I made a function for factorials and used that to calculate binomial coefficients. it worked fine for small values like n=10 and r=5 etc... but for large a medium value like 23C12 it gave 4 as answer.
IDK what is wrong with the code or I forgot to add something.
My code:
#include <iostream>
using namespace std;
int fact(int n)
{
int a = 1;
for (int i = 1; i <= n; i++)
{
a *= i;
}
return a;
}
int main()
{
int n, r;
cin >> n >> r;
if (n >= r)
{
int coeff = fact(n) / (fact(n - r) * fact(r));
cout << coeff << endl;
}
else
{
cout << "please enter valid values. i.e n>=r." << endl;
}
return 0;
}
Thanks for your help!
You're not doing anything "wrong" per se. It's just that factorials quicky become huge numbers.
In your example you're using ints, which are typically 32-bit variables. If you take a look at a table of factorials, you'll note that log2(13!) = 32.535.... So the largest factorial that will fit in a 32-bit number is 12!. For a 64-bit variable, the largest factorial you can store is 20! (since log2(21!) = 65.469...).
When you get 4 as the result that's because of overflow.
If you need to be able to calculate such huge numbers, I suggest a bignum library such as GMP.
Factorials overflow easily. In practice you rarely need bare factorials, but they almost always appear in fractions. In your case:
int coeff = fact(n) / (fact(n - r) * fact(r));
Note the the first min(n,n-r,r) factors of the denominator and numerator are identical. I am not going to provide you the code, but I hope an example will help to understand what to do instead.
Consider n=5, r=3 then coeff is
5*4*3*2*1 / 2*1 * 3*2*1
And before actually carrying out any calculations you can reduce that to
5*4 / 2*1
If you are certain that the final result coeff does fit in an int, you can also calculate it using ints. You just need to take care not to overflow the intermediate terms.

Binary Conversion with recursive fucntion is giving an odd value

I am making a function that converts numbers to bianry with a recursive function, although when I write big values, it is giving me an odd value, for example, when I write 2000 it gives me the result of -1773891888. When I follow the function with the debugger it gives me the correct value of 2000 in binary until the last second.
Thank you!!
#include <iostream>
int Binary(int n);
int main() {
int n;
std::cin >> n;
std::cout << n << " = " << Binary(n) << std::endl;
}
int Binary(int n) {
if (n == 0)return 0;
if (n == 1)return 1;
return Binary(n / 2)*10 + n % 2;
}
Integer values in C++ can only store values in a bounded range (usually -231 to +231 - 1), which maxes out around two billion and change. That means that if you try storing in an integer a binary value with more than ten digits, you’ll overflow this upper limit. On most systems, this causes the value to wrap around, hence the negative outputs.
To fix this, I’d recommend having your function return a std::string storing the bits rather than an integer, since logically speaking the number you’re returning really isn’t a base-10 integer that you’d like to do further arithmetic operations on. This will let you generate binary sequences of whatever length you need without risking an integer overflow.
At least your logic is correct!

Negative output in Fibonacci sequence

I am getting negative output when adding large numbers in Fibonacci sequence despite using long int. How to fix that?
#include <iostream>
using namespace std;
void main() {
long int sum = 2;
long int f1 = 1, f2 = 2, f3;
for (unsigned int i = 2; i < 4000000; i++) {
f3 = f2 + f1;
if (!(f3 % 2)) {
sum += f3;
}
swap(f1, f2);
swap(f2, f3);
}
cout << sum << endl;
}
The output is -1833689714
As you can see here the 47th Fibonacci Number exceeds the range of a 32Bit/4Byte integer. Everything after that will become negative.
For your program you used a long int which may or may not be 32 or 64 bits wide, the C++ standard does not guarantee that (for good reasons). If I see your result it seems like 32 Bit for me.
First, to prevent negativeness, you could use unsigned long int which makes all your results positive and gives the ability to model "slightly" bigger numbers.
However you will still get the wrong results if you pass the 47th Fibonacci number since your data type is still too small. To fix this you could use unsigned long long or uint64_t.
Remember even for such big datatypes that can represent numbers up to approx. 18 trillion/quintillion (10^18) the Fibonacci numbers exceed this at the 89th iteration.
Try with this code:
#include<iostream>
using namespace std;
int main()
{
cout<<"Enter Number:";
unsigned long long int x;
cin>>x;
unsigned long long int a=0,b=1,c;
cout<<a<<"\t"<<b;
for(int i=0;i<x;i++)
{
c=a+b;
cout<<"\t"<<c;
a=b;
b=c;
return 0;
}
}

What is the C++ function to raise a number to a power?

How do I raise a number to a power?
2^1
2^2
2^3
etc...
pow() in the cmath library. More info here.
Don't forget to put #include<cmath> at the top of the file.
std::pow in the <cmath> header has these overloads:
pow(float, float);
pow(float, int);
pow(double, double); // taken over from C
pow(double, int);
pow(long double, long double);
pow(long double, int);
Now you can't just do
pow(2, N)
with N being an int, because it doesn't know which of float, double, or long double version it should take, and you would get an ambiguity error. All three would need a conversion from int to floating point, and all three are equally costly!
Therefore, be sure to have the first argument typed so it matches one of those three perfectly. I usually use double
pow(2.0, N)
Some lawyer crap from me again. I've often fallen in this pitfall myself, so I'm going to warn you about it.
In C++ the "^" operator is a bitwise XOR. It does not work for raising to a power. The x << n is a left shift of the binary number which is the same as multiplying x by 2 n number of times and that can only be used when raising 2 to a power, and not other integers. The POW function is a math function that will work generically.
You should be able to use normal C methods in math.
#include <cmath>
pow(2,3)
if you're on a unix-like system, man cmath
Is that what you're asking?
Sujal
Use the pow(x,y) function: See Here
Just include math.h and you're all set.
While pow( base, exp ) is a great suggestion, be aware that it typically works in floating-point.
This may or may not be what you want: on some systems a simple loop multiplying on an accumulator will be faster for integer types.
And for square specifically, you might as well just multiply the numbers together yourself, floating-point or integer; it's not really a decrease in readability (IMHO) and you avoid the performance overhead of a function call.
I don't have enough reputation to comment, but if you like working with QT, they have their own version.
#include <QtCore/qmath.h>
qPow(x, y); // returns x raised to the y power.
Or if you aren't using QT, cmath has basically the same thing.
#include <cmath>
double x = 5, y = 7; //As an example, 5 ^ 7 = 78125
pow(x, y); //Should return this: 78125
if you want to deal with base_2 only then i recommend using left shift operator << instead of math library.
sample code :
int exp = 16;
for(int base_2 = 1; base_2 < (1 << exp); (base_2 <<= 1)){
std::cout << base_2 << std::endl;
}
sample output :
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
It's pow or powf in <math.h>
There is no special infix operator like in Visual Basic or Python
#include <iostream>
#include <conio.h>
using namespace std;
double raiseToPow(double ,int) //raiseToPow variable of type double which takes arguments (double, int)
void main()
{
double x; //initializing the variable x and i
int i;
cout<<"please enter the number";
cin>>x;
cout<<"plese enter the integer power that you want this number raised to";
cin>>i;
cout<<x<<"raise to power"<<i<<"is equal to"<<raiseToPow(x,i);
}
//definition of the function raiseToPower
double raiseToPow(double x, int power)
{
double result;
int i;
result =1.0;
for (i=1, i<=power;i++)
{
result = result*x;
}
return(result);
}
Many answers have suggested pow() or similar alternatives or their own implementations. However, given the examples (2^1, 2^2 and 2^3) in your question, I would guess whether you only need to raise 2 to an integer power. If this is the case, I would suggest you to use 1 << n for 2^n.
pow(2.0,1.0)
pow(2.0,2.0)
pow(2.0,3.0)
Your original question title is misleading. To just square, use 2*2.
First add #include <cmath> then
you can use pow methode in your code for example :
pow(3.5, 3);
Which 3.5 is base and 3 is exp
Note that the use of pow(x,y) is less efficient than x*x*x y times as shown and answered here https://stackoverflow.com/a/2940800/319728.
So if you're going for efficiency use x*x*x.
I am using the library cmath or math.h in order to make use of the pow() library functions that takes care of the powers
#include<iostream>
#include<cmath>
int main()
{
double number,power, result;
cout<<"\nEnter the number to raise to power: ";
cin>>number;
cout<<"\nEnter the power to raise to: ";
cin>>power;
result = pow(number,power);
cout<<"\n"<< number <<"^"<< power<<" = "<< result;
return 0;
}
use pow() function in cmath, tgmath or math.h library.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int a,b;
cin >> a >> b;
cout << pow(a,b) << endl; // this calculates a^b
return 0;
}
do note that if you give input to power as any data type other than long double then the answer will be promoted to that of double. that is it will take input and give output as double. for long double inputs the return type is long double. for changing the answer to int use,
int c=(int)pow(a,b)
But, do keep in mind for some numbers this may result in a number less than the correct answer. so for example you have to calculate 5^2, then the answer can be returned as 24.99999999999 on some compilers. on changing the data type to int the answer will be 24 rather than 25 the correct answer. So, do this
int c=(int)(pow(a,b)+0.5)
Now, your answer will be correct.
also, for very large numbers data is lost in changing data type double to long long int.
for example you write
long long int c=(long long int)(pow(a,b)+0.5);
and give input a=3 and b=38
then the result will come out to be 1350851717672992000 while the correct answer is 1350851717672992089, this happens because pow() function return 1.35085e+18 which gets promoted to int as 1350851717672992000. I suggest writing a custom power function for such scenarios, like:-
long long int __pow (long long int a, long long int b)
{
long long int q=1;
for (long long int i=0;i<=b-1;i++)
{
q=q*a;
}
return q;
}
and then calling it whenever you want like,
int main()
{
long long int a,b;
cin >> a >> b;
long long int c=__pow(a,b);
cout << c << endl;
return 0;
}
For numbers greater than the range of long long int, either use boost library or strings.
int power (int i, int ow) // works only for ow >= 1
{ // but does not require <cmath> library!=)
if (ow > 1)
{
i = i * power (i, ow - 1);
}
return i;
}
cout << power(6,7); //you can enter variables here