i have written a small function which calculates factorial for a number in C
as follows:
int factNnumbers(int n)
{
if(n == 1)
return 1;
else
return (n*factNnumbers(--n));
}
I call the function shown above as:
factNnumbers(takeInputN());
where the function to take the input (takeInputN) is defined as:
int takeInputN()
{
int n;
printf("\n\nHow many numbers ?? \n ");
scanf("%d", &n);
return n;
}
If I change one line in my factorial code as shown below , my program works perfectly. Otherwise with the above code it prints the factorial of the number input -1 (example if number input is 5, it will print the factorial of 4). Why is this happening?.
int factNnumbers(int n)
{
if(n != 1)
return (n * factNnumbers(--n));
}
The problem is that you're both reading and modifying n in the same expression:
n * factNumbers(--n)
The evaluation of the n argument to * and of the --n subexpression are unsequenced, which gives your code Undefined Behaviour.
The easiest solution (and also, IMO, more expressive), is to say n - 1 where you mean it:
n * factNumbers(n - 1)
Your "improved" code in the bottom of the question is actually even more wrong. There, you have a control path which will return an unspecified value: a clear no-no.
Note: This answer was written while the question still had a C++ tag, and uses C++ terminology. The end effect in C is the same, but the terminology might be different.
You are invoking undefined behaviour, that it works in one version is just an accident:
return (n*factNnumbers(--n));
Do you use n first and then decrement it or the other way around? I don't know and neither does the compiler, it's free to do either of them or format your hard drive. Just use n * f(n - 1).
Also, your "working" version does not return for the n==1 case, which is illegal.
There are two causes of undefined behavior in your code:
Whether n or --n in n * factNnumbers(--n) will be evaluated first is unspecified.See this. You want just n * factNnumbers(n - 1), why decrement? You're not using decremented n afterwards (at least you didn't want to).
You're not returning a value on all control paths, what's going to be returned on n == 1? An indeterminate value that will mess up the whole result.
the rule of decrement:
X = Y-- first passes the value of I to X and decrements after
X = --I first pass and decrements the value decremented X
for your case, you decrement the value of parameter passed as argument to the function factNnumbers. Therefore remedy this error, I invite you to put (n-1) instead of (--n).
I think it’s better to use the tgamma function from math.h for double precision calculations involving factorials (such as Poisson distribution etc.): tgamma(n+1) will give you factorial(n).
Factorial function is increasing very fast, and this will work also for values too big to fit an integer type.
When n<=1 (or == 1 in your code), the factorial function has to return 1. Futhermore the your --n in you code is false and sould be n-1 as:
function factorial(n)
{
if (n<=1)
return 1;
else
return n * factorial(n-1);
}
Related
I am getting an output of 24 which is the factorial for 4, but I should be getting the output for 5 factorial which is 120
#include <stdio.h>
int factorial(int number){
if(number==1){
return number;
}
return number*factorial(--number);
}
int main(){
int a=factorial(5);
printf("%d",a);
}
Your program suffers from undefined behavior.
In the first call to factorial(5), where you have
return number * factorial(--number);
you imagine that this is going to compute
5 * factorial(4);
But that's not guaranteed!
What if the compiler looks at it in a different order?
What it if works on the right-hand side first?
What if it first does the equivalent of:
temporary_result = factorial(--number);
and then does the multiplication:
return number * temporary_result;
If the compiler does it in that order, then temporary_result will be factorial(4), and it'll return 4 times that, which won't be 5!. Basically, if the compiler does it in that order -- and it might! -- then number gets decremented "too soon".
You might not have imagined that the compiler could do things this way.
You might have imagined that the expression would always be "parsed left to right".
But those imaginations are not correct.
(See also this answer for more discussion on order of evaluation.)
I said that the expression causes "undefined behavior", and this expression is a classic example. What makes this expression undefined is that there's a little too much going on inside it.
The problem with the expression
return number * factorial(--number);
is that the variable number is having its value used within it, and that same variable number is also being modified within it. And this pattern is, basically, poison.
Let's label the two spots where number appears, so that we can talk about them very clearly:
return number * factorial(--number);
/* A */ /* B */
At spot A we take the value of the variable number.
At spot B we modify the value of the variable number.
But the question is, at spot A, do we get the "old" or the "new" value of number?
Do we get it before or after spot B has modified it?
And the answer, as I already said, is: we don't know. There is no rule in C to tell us.
Again, you might have thought there was a rule about left-to-right evaluation, but there isn't. Because there's no rule that says how an expression like this should be parsed, a compiler can do anything it wants. It can parse it the "right" way, or the "wrong" way, or it can do something even more bizarre and unexpected. (And, really, there's no "right" or "wrong" way to parse an undefined expression like this in the first place.)
The solution to this problem is: Don't do that!
Don't write expressions where one variable (like number) is both used and modified.
In this case, as you've already discovered, there's a simple fix:
return number * factorial(number - 1);
Now, we're not actually trying to modify the value of the variable number (as the expression --number did), we're just subtracting 1 from it before passing the smaller value off to the recursive call.
So now, we're not breaking the rule, we're not using and modifying number in the same expression.
We're just using its value twice, and that's fine.
For more (much more!) on the subject of undefined behavior in expressions like these, see Why are these constructs using pre and post-increment undefined behavior?
How to find the factorial of a number;
function factorial(n) {
if(n == 0 || n == 1 ) {
return 1;
}else {
return n * factorial(n-1);
}
//return newnum;
}
console.log(factorial(3))
#include <stdio.h>
#include <math.h>
void foo (int n, int k){
int rez=1;
int trenutnirez;
int highest_exp=0;
if (k<2 || k>16){
printf ("INCORRECT");
return NULL;
}
while (rez<n){
rez*=k;
highest_exp++;
}
rez=n;
highest_exp--;
}
int main (){
foo(200,8);
return 0;
}
I get to here and calculate the highest exponent, dunno where to next?
this is my collage lab, don't usually ask here so feel free to be as slow as possible with me.
What you're tasked with is number conversion from base 10 to other bases (namely base 2 to base 16).
Essentially,
n = coef(xp) * b^(xp) + coef(xp-1) * b^(xp-1) + ... + coef(1) * b^(0) + coef(0) * b^(0)
where the following are non-negative integers:
n is the given number,
coef(t) represents the coefficient with index t,
b is the base to which you're converting, and
xp is the highest exponent.
The way this is done is by repeated division and remainder operations. In pseudo code:
for i = xp to 0 inclusive:
coef = n / b**i // '/' is integer division, '**' is exponentiation
n = n % b**i // '%' is the remainder operation
if coef > 0:
if i != xp:
print " + "
endif
print coef, " * ", b, "**", i
endif
endfor
From this a fairly straightforward implementation can be done in C. Note that you might want to cache the value of b**i so that it isn't calculated multiple times, and that you need a function to perform the calculation in the first place (I recommend you write one yourself) since C doesn't offer an exponentiation operator, except for binary numbers.
A couple of comments on the code you've written so far:
one of the standard-prescribed definitions of the main function when it doesn't take any arguments is int main(void) { ... } – don't deviate from that, unless you're trying to invoke some implementation-defined behavior for your particular implementation;
returning NULL from a function whose return type is void is undefined behavior (from 6.8.6.4, C99 standard):
A return statement with an expression shall not appear in a function whose return type is void.
what you instead want here is to return EXIT_FAILURE; (and change the type of value your function returns) and handle that in the calling function, or call exit(EXIT_FAILURE);, which causes normal process termination, with EXIT_FAILURE and exit being declared in stdlib.h; alternatively, a simple expressionless return; will do.
A couple of other observations:
trenutnirez is uninitialized and unused;
normally you want to append a newline when you're writing to standard output, which means appending \n to your printf's format string, or simply using puts, which will do that automatically for you;
consider declaring all your function prototypes at the top: this is useful because when you have multiple functions, you don't have to worry about which function comes first in order for all of them to be "visible" in all your functions (e.g., if you now add the exponentiation function below foo, which by the way you should rename to something more appropriate, it won't know the new function's signature).
Below is the recursive function for sum of natural numbers up to n.
int calculateSum(int n) {
if (n == 0){
return 0;
}else{
return n + calculateSum(--n); //Replacing --n with n-1 works
}
}
Input: 5
If I use --n then the output is 10, but when I replace --n with n - 1 then the correct result is returned (15). Why the difference?
As surprising as it might be, the behaviour of the expression
n + calculateSum(--n);
is undefined, because --n not only evaluates to the value of n after being decremented by 1, it also changes n to the new value. The change (a side effect), however, is unsequenced in relation to the other evaluation of n (a value computation) on the left. And according to C11 Appendix J.2., the behaviour is undefined, when
A side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object (6.5).
More of the same class of errors in this question.
You can consider yourself lucky when you got a wrong value, because your compiler could have also generated code that would return the "correct value"... given the phase of the moon, and the optimization settings, or the number of lines in the calling function...
--n also modifies the local variable n; the expression n-1 just returns the decremented value to pass it on to the recursive call, but does not modify your input-parameter.
In detail for the first iteration with input 5:
Correct is return 5 + calculateSum(5-1);
With --n you would also decrement from n and end up with 4 + calculateSum(4)
#user3386109 & #Yunnosch worded it this way:
With --n you calculate the sum 0...(5-1) instead of 0...5.
See #Antti answer, it explains that it's actually undefined behaviour.
The following code snippet (a Function), you can call it in the main function which will return the sum of n natural numbers recursively
int NNumbers(int n)
{
if(n != 0)
return n + NNumbers(n-1);
else
return n;
}
In your code you are decrementing the value of n and then you are calculating the sum (i,e. Pre-Decrement), since the input is 5, it decrements 1 at each iteration and and then it will go for addition of natural numbers. so you are getting the result 10 instead of 15
Hope this helps for you :)
Thank you
how is your day :),
Take a look at the below program, the program written below is to calculate the sum of first n natural numbers, the problem is that i get the sum of n-1 natural numbers, can anybody explain why ?
and can anybody also explain why a-- instead of --a.
#include<stdio.h>
main()
{
int a,sum;
printf("Enter a number.");
scanf("%d",&a);
sum=sumnat(a);
printf("Sum of the first %d natural numbers is %d.",a,sum);
}
sumnat(a)
{
int b;
if(a==0)
{
return 0;
}
else
{
b=a+sumnat(--a);
return(b);
}
}
There were several errors, the greatest of which was undefined behaviour in the expression which uses a and also a modified value of a. You should also define your function properly, not rely on default values provided by the compiler.
#include <stdio.h>
int sumnat(int a); // function prototype
int main(void) // correct signature
{
int a, sum;
printf("Enter a number. ");
scanf("%d", &a);
sum = sumnat(a);
printf("Sum of the first %d natural numbers is %d.", a, sum);
return 0;
}
int sumnat(int a) // function has a return type and argument type
{
if(a == 0)
{
return 0;
}
return a + sumnat(a - 1); // there was no need to decrement `a`
}
Program session
Enter a number. 5
Sum of the first 5 natural numbers is 15.
Your program works for me, using gcc on Mac OSX. However, it will not work everywhere, because of this line:
b=a+sumnat(--a);
--a decrements a, but if it does so before the addition, then your result will be wrong. I'm not sure C is required to evaluate expressions strictly left-to-right (I don't think it is). At any rate, since you don't use a after that line, you could fix things this way:
b=a+sumnat(a-1);
As #self says, you should fix the program to handle negative values, and it would be a good idea to consider what is the largest natural number whose sum you can compute this way (and why that is).
There is a difference between them. One first subracts from a and than goes in the function while the other frist goes in... so it never gets subracted and you go to inifinit stack.
"and can anybody also explain why a-- instead of --a"
When you use the prefix operator --a the decrease is done before anything else, while the postfix operator a-- happens after the rest of the expression is resolved, so, lets say, while debugging your code, in a particular moment, a = 5
since the line
b=a+sumnat(--a);
is using the prefix version of the operator, the decrement would happen immediately, making a=4 and then the function sumnat would be called with argument 4
b=a+sumnat(a--);
in this case the postfix operator is being used, so first the function sumnat would be called with the argument 5, since that is the value of a in that moment, then, only when the function returns a value (which would never happen in your example, since it would be called multiple times with the same value, never reaching 0) the decrement would happen
int reverse(int);
void main()
{
int no =5;
reverse(no);
}
int reverse(int no)
{
if(no == 0)
return 0;
else
printf("%d",no);
reverse(no--);
}
This program goes in infinite loop.Why is that so? I am not able to get the desired ouput.
Desired output should be 5 4 3 2 1.Thank you in advance
In this recursive call:
reverse(no--);
You are passing the value of no--. Since this uses the postfix -- operator, this means "decrement no, then pass the original value of no into the recursive call to reverse." This causes infinite recursion, since you are constantly making a recursive call with reverse set to the same value.
To fix this, change this to read
reverse(no - 1);
Notice that there's no reason to decrement no here, since within the current recursive call you will never read no again. You can just pass the value of no - 1 into the function. In fact, you might want to in general avoid using -- in recursive calls, since it almost always indicates an error in the code.
Hope this helps!
You're using the post-decrement operator on no. That first gets the value of no and uses that as the value of the expression and then decrements no (still using the undecremented value as the value of the expression). You probably want to use --no or even just no - 1. (The former will modify no, whereas the latter will not, but it does not matter because no is not referenced after that point.)
Change:
reverse(no--);
to:
reverse(no-1);
no-- returns the original value before the decrement occurred. So this line will always call reverse(5). Hence, infinite loop.
n-- is post increment which first use n as argument of the function and then decrement n.
So n-- essentially does is
reverse(n);
n = n - 1;
What you want is --n
You are using post-decrement. First evaluates, then reduces value.
Change this:
reverse(no--);
to this:
return reverse(--no);
--no is pre-decrement. First decrease "no", then pass the value to reverse.
Note that I'm RETURNING the result value, you function always have to return an int, due to its declaration.
You want to do
int reverse(int);
int main()
{
int no =5;
reverse(no);
}
int reverse(int no)
{
if(no == 0)
return 0;
else
printf("%d",no);
return reverse(--no);
}
So that you're returning a number every time you call reverse and you decrement no before you use it.