This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 5 years ago.
int fact_rec(int n)
{
printf("%d\n",n);
if(n==1) return n;
else return fact_rec(--n)*n;
//else return n*fact_rec(--n); gives same result
//correct output comes for n*fact(n-1)
}
In the above recursive implementation of the factorial function,
fact_rec(5) returns 24. Whereas, if I use
n*fact_rec(n-1)
in place of
n*fact_rec(--n)
the output is correct : 120.
Also, it doesn't matter whether I use
n*fact_rec(--n)
or
fact_rec(--n)*n.
Shouldn't it matter if I use
n*fact_rec(--n)
or
fact_rec(--n)*n?
And shouldn't the output have
been 120 in all the cases?
return fact_rec(--n)*n
is dangerous. The order of argument evaluation is undefined in C (except for &&, ||, comma and ternary operators) so value for second occurrence of n could vary.
The rule of thumb: never use variable you are incrementing/decrementing twice in one expression.
Your confusion seems to be about the order - unlike the other answers, I am assuming you already know what --n does...
The compiler knows it needs the value of fact_rec(--n) before it can evaluate fact_rec(--n)*n whichever way round you write it, so the function is evaluated first, and the value of n multipled has always already been decremented.
There is actually no need to modify n at all. return n * fact_rec(n - 1) takes care of it and is the right way to do it.
--n in your function really means:
int fact_rec(int n) {
printf("%d\n",n);
if(n==1) {
return n;
} else {
n = n - 1; /* <---- effect of --n */
return fact_rec(n)*n;
}
}
The problem is here:
else return fact_rec(--n)*n;
you're decrementing n before the multipliation
so if n starts as 5 it runs as
return fact_rec(4)*4;
Edit: Down voted for a correct answer to the question? I don't get it.
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))
This question already has answers here:
What is the difference between ++i and i++?
(20 answers)
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 4 years ago.
I've recently started trying to learn C & was doing an exercise that involved creating a recursive factorial function.
Why does the following print out an answer of 24?
#include <stdio.h>
int factorial(int n);
int main(void)
{
int n = 5;
printf("%d\n", factorial(n));
return 0;
}
int factorial(int n)
{
if (n <= 1)
return 1;
else
return n * factorial(--n);
}
If i change the last line to
return n * factorial(n - 1);
I get the expected 120.
I understand that you can't use n-- b/c it only decreases n after the line is processed but whats wrong with --n & why does it give 24?
whats wrong with --n & why does it give 24?
The problem is that --n modifies n, so your line
return n * factorial(--n);
may evaluate like:
return (n - 1) * factorial(n - 1);
because the factorial(--n) is evaluated before the n that is the first term of the expression. On the other hand, the first term could be evaluated before the second, and you'd get the result you expect. Or, something entirely different could happen, because (as M.M and David C. Rankin point out in comments) what happens when you try to use a variable and modify it in the same expression is undefined:
If 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, the behavior is undefined.
So let's address your title question:
Does (--n) equal (n - 1)?
The values of --n and of n - 1 are the same, but the former expression has the side effect that it modifies n. You should really think of --n as being shorthand for the expression (n = n - 1).
This question already has answers here:
The ternary (conditional) operator in C
(14 answers)
Closed 5 years ago.
my confusion is that how in the program the number of positive and negative numbers are calculated by writing that piece of code shown.
explain these code please!
int num[5], i, neg = 0, pos = 0;
printf("enter any 5 numbers");
for (i = 0; i <= 4; i++)
scanf("%d", &num[i]);
for (i = 0; i <= 4; i++) {
num[i] < 0 ? neg++ : (pos++);
}
printf("\nnegative elements=%d", neg);
printf("\npositive elements=%d", pos);
getch();
num[i]<0?neg++:(pos++);
Here, If number less then zero then condition become true and count the negative numbers and If number not less then zero then condition become false and count positive numbers.
The line
num[i]<0?neg++:(pos++);
means- compare num[i] to 0, if it is lower, increase the variable neg. Otherwise (num[i] >= 0), increase the variable pos.
hope this helps
Since, most answers have explained the ternary operator, I need not do it again.
The neg++ post-increments the previous value of neg variable. And the same goes for pos++.
Here's a link on post/pre increments.
The ternary operator used as an expression statement evaluates like an if statement:
num[i] < 0 ? neg++ : (pos++);
is equivalent to
if (num[i] < 0)
neg++;
else
pos++;
This kind of coding is not considered good style, and there are other issues in the code fragment posted:
the return value of scanf() should be checked to avoid undefined behavior if the input cannot be converted to an int.
the loop index should be compared to the array size with i < 5 instead of using the <= operator and a close but different constant.
output lines should be terminated with newline, not initiated with one.
getch() is a non standard function. Its purpose is to force a pause before the program exits. Fixing shortcomings of the environment inside the program is a sad workaround. Opening a terminal window to execute programs is a better alternative: it allows the programmer to observe all program output including any extra runtime messages occurring upon program termination.
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);
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is really happening in this code?
I have a code which includes a recursive function. I have wasted a lot of time on recursion, but i still couldn't get it, really:
#include<stdio.h>
count(int);
main(){
int x=10,z;
z=count(x);
}
count(int m){
if(m>0)
return count(m-1);
}
When count is called for the first time with argument 10, it fulfils the condition and the recursion starts. What happens really when a function calls itself? I dont get it. What does the statement return count(m-1) mean? Where does it tranfer the control?
The return value of the function count is undefined, because there is no default return if (m <= 0) is true.
C11, § 6.9.1 Function definitions
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
Besides, to understand how a recursive function works, you have to take a paper and try to execute the code by yourself (see also here).
You need count to return something when m <= 0. You should declare the return type of count and compile with -Wall so the compiler will help you find mistakes in your code.
recursion means that the function will call itself, mostly at the end of itself, if it's tail recursion.
So your count function checks that the input argument is > 0 and then if it is, it will call count(m-1). Now it starts at the top of count with m=9. It does the same thing, and then calls count with m=8, etc.
Until the end condition is reached, which should normally be explicitly catered for in your function, such as if (m == 0) return m; or some such thing. At that point the recursion ends and the function terminates.
Also, count should have a return type, such as int count (int m)
what does the statement return count(m-1) mean ? where does it tranfer the control?
That seems to be your only question.
it means that it is calling "count" with the value m-1. So if m was 10, then it is calling "count" with 9.
It is transferring the control recursively to the count method.
You also don't have a return for the every possible path in the "count" method.
What happens if m is <= 0?