Hi I have implemented a C code in visual C++ and and did some modification in it for debugging. Here is the code
long long unsigned factorial(long long unsigned int * n) {
if (*n<=1) return 1;
else {
(*n)--;//This statement here .......
printf("calculating %d * factorial %d \n",*n,*n); -- used for debugging
return ((*n+1) * factorial(n));
}
}
The final output(value of factorial) is coming as expected but it is output of debug statement that surprises me.
calculating 4 * factorial 0
calculating 3 * factorial 0
calculating 2 * factorial 0
calculating 1 * factorial 0
120
Same value *n is used twice in every debug statement and it is showing different values. How is this possible that same value when used twice in a statement, gives different results.
I'm only guessing here, but the format code "%d" is for int, while you pass a long long. That's a difference of 32 bits per value. Use "%llu" instead ("ll" for long long, the "u" for unsigned).
Because you are using a wrong format for unsigned long long, test this one:
#include <stdio.h>
long long unsigned factorial(long long unsigned int * n) {
if (*n<=1) return 1;
else {
(*n)--;//This statement here .......
printf("calculating %llu * factorial %llu \n",*n,*n);
return ((*n+1) * factorial(n));
}
}
int main(void)
{
long long unsigned int n = 4ULL;
n = factorial(&n);
printf("%llu\n", n);
return 0;
}
You are modifying the value of n at each recursion iteration.
When you are using recursion with a pointer:
return ((*n+1) * factorial(n));
You first calculating the value of factorial(n). When the last recursion iteration is reached, you already decremented the n till 0.
So, please do not pass n by reference .
Related
I had to make a recursive function that use only multiplication operation to get the answer of X in power of N.
I wrote this:
#include <stdio.h>
int power(int x, int n);
int main()
{
int x, n;
printf("Enter base and exponent:\n");
scanf("%d%d", &x, &n);
printf("%d\n", power(x, n));
return 0;
}
int power(int x, int n)
{
if (n==0) return 1;
return x*power(x, n*0.5);
}
So its works good for small number, like if the input x=3, n=2 the output will be 9 which is good. But when I input bigger numbers, for example: x=362, n=123 the output will be -79249792 which its wrong.
Can someone help me understand what's wrong?
(Im using Online C Compliler {OnlineGBD})
First, the recursion you implemented shouldn't work for small numbers too, since as others have pointed out, x^n = (x^(n/2))^2 and not x*(x^(n/2)), and for odd values of n, n/2 will get truncated since the function takes integer arguments. Try 2^3, your code gives answer 4. A simple way to fix this is via using the following recursion : x^n = x*(x^(n-1)), or if you want to make the code more efficient, use this algorithm.
But this still doesn't address negative numbers showing up. The problem is max size of int is 2^31-1 = 2,14,74,83,647. This is due the way it is stored in memory, occupying 32 bits. What happens when you cross this limit? It overflows, and becomes -2^31. So you won't be able to get correct answers for big numbers. Generally this is handled by calculating the answer modulo some prime number, or creating arbitrary precision data structures. Check out this and this.
First of all, please remove this:
printf("Enter base and exponent:\n");
scanf("%d%d", &x, &n);
printf("%d\n", power(x, n));
and write a simple, easy to run test harness that doesn't involve thinking and typing input into the console, with clear output of expected/actual values on failure:
#include <math.h>
#include <stdio.h>
int power(int base, int exponent) {
return 1;
}
int main(void) {
for (int base = 0; base < 5; base++) {
for (int exponent = 0; exponent < 5; exponent++) {
int expected = (int)pow(base, exponent);
int actual = power(base, exponent);
if (expected != actual) {
printf("[FAIL] power(%d, %d) was: %d\n"
" expected: %d\n\n",
base, exponent, actual, expected);
}
}
}
return 0;
}
Notice the clearer parameter names on the power function and usage of the built-in pow to ensure correct logic.
Now let's test your algorithm:
[FAIL] power(2, 3) was: 4
expected: 8
[FAIL] power(2, 4) was: 8
expected: 16
[FAIL] power(3, 3) was: 9
expected: 27
[FAIL] power(3, 4) was: 27
expected: 81
[FAIL] power(4, 3) was: 16
expected: 64
[FAIL] power(4, 4) was: 64
expected: 256
It appears that n*0.5 isn't giving the correct reduction factor.
Taking a step back, exponentiation by multiplication is done by repeatedly multiplying base by itself exponent times and accumulating onto a result initialized to 1:
int power(int base, int exponent) {
int result = 1;
for (int i = 0; i < exponent; i++) {
result *= base;
}
return result;
}
Since we're forced to use recursion, the problem reduces to simulating the classic counting loop above with recursion.
This can be done by subtracting 1 from the exponent per call until we reach 0 (<= 0 is a safer base case than == 0, avoiding blowing the stack on negative input).
As for the return value, you're correct in returning 1 for n == 0 and multiplying base on each frame by the child's value, which is the same as the *= operation in the iterative version.
Here's the fixed code:
int power(int base, int exponent) {
if (exponent <= 0) {
return 1;
}
return base * power(base, exponent - 1);
}
Finally, x=362, n=123 fails because of integer overflow. 362**123 has 315 digits, but 4 byte numbers like int only hold 10-ish. You'll need a big integer library to handle that massive an input.
Note that I haven't attempted to handle negative numbers here. I assume that's out of scope. Making the parameters unsigned would help enforce this contract.
Beginner in C language.
I suspect it may be due to overflow, but could not solve this simple exercise:
program to compute the sum of squares of all the natural numbers smaller than 10000
I initially tried:
#include <stdio.h>
int main() {
int a = 10000;
int square(int num) {
return num * num;
};
int total = 0;
while (a > 0) {
a--;
total += square(a);
//printf("a is %d and square is %d and total %d \n", a, square(a), total );
};
printf("total is %d ", total );
return total;
}
result: total is -1724114088
and here there's the strange thing:
...
a is 9936 and square is 98724096 and total 2063522144
a is 9935 and square is 98704225 and total -2132740927
...
So I tried to change total to long, tried to change declaring square function as long square(int num ), but nothing changed.
Could you explain why the sum turns negative ?
Is it due to overflow ? But why not resetting to 0 or positive, instead of going negative ?
how can I know how many bits for int are there in a computer that I don't know (e.g. cloud ?
E.g. I am coding here: [https://www.programiz.com/c-programming/online-compiler/]
Which is best practice to fix it ?
Do not define function in functions.
int main() {
int square() { // NO!
Functions belong at file scope:
int square() { //OK
}
int main() { //OK
}
The code compiles because compilers have extensions to the language. It's not part of the C programming language.
Could you explain why the sum turns negative ?
See ex. why the value of sum is coming out to be negative? and other questions. The sum "wraps around" on your platform.
Is it due to overflow ?
Yes.
But why not resetting to 0 or positive, instead of going negative ?
Because systems nowadays are twos-complement, it's simpler to implement a single hardware instruction for adding numbers then two separate instructions with special overflow semantics. Unsigned and signed twos-complement numbers behave the same when doing operations on them, so instead of doing special semantics on overflow, when adding signed numbers they are added the same as they would be unsigned (bits are just added) and the result is then interpreted as a signed number (in a C program), which because the most significant bit becomes set the number becomes negative.
Anyway, compiler just does not care, because signed overflow is undefined behavior compiler does not have to care. The compiler just generates a hardware instruction for signed addition, which behaves as explained above.
how can I know how many bits for int are there in a computer that I don't know
You can check your compiler documentation.
But usually it's simpler to just compile a simple C program where you use CHAR_BIT - the number of bits in a byte - and sizeof(int) - the number of bytes in an int - and inspect the output of that program. For example, a program such as:
#include <stdio.h>
#include <limits.h>
int main() {
printf("There are %d bits in int\n", (int)sizeof(int) * CHAR_BIT);
}
Note that number of bits in types does not only change with platform and operating systems, it can change with compiler, compiler versions and also compilation options.
Which is best practice to fix it ?
This depends on what behavior do you want.
To calculate bigger values use a bigger datatype - long or long long. When the language features are not enough, move your program to use some big number library.
If you want to terminate the program in case of problems - you can check for overflow and call abort() or similar if it happens.
Instead, you could have used a formula.
Sum of Squares of first N natural numbers = (N * (N + 1) * (2 * N + 1) / 6
For now, let N be 10000.
Ignoring the 6 in the formula, the sum of squares is as big as 10^12. It will not fit in an integer. You should use a data type that can accommodate bigger values, like long or long long int.
Here's the modified code.
#include <stdio.h>
int main() {
int a = 10000;
int square(int num) {
return num * num;
};
// Change int to long long int
long long int total = 0;
while (a > 0) {
a--;
total += square(a);
//printf("a is %d and square is %d and total %d \n", a, square(a), total );
};
// Change %d to %lld
printf("total is %lld ", total );
return total;
}
You'll need to change all uses of int to long:
#include <stdio.h>
int main() {
long a = 10000;
long square(long num) {
return num * num;
};
long total = 0;
while (a > 0) {
a--;
total += square(a);
//printf("a is %ld and square is %ld and total %ld \n", a, square(a), total );
};
printf("total is %ld ", total );
return 0;
}
which prints total is 333283335000
EDIT
Or you could just change the total, the return type of square, and perform the appropriate casts when computing the squared values:
#include <stdio.h>
int main() {
int a = 10000;
long square(int num) {
return (long)num * (long)num;
};
long total = 0;
while (a > 0) {
a--;
total += square(a);
//printf("a is %ld and square is %ld and total %ld \n", a, square(a), total );
};
printf("total is %ld ", total );
return 0;
}
Produces the same result shown above.
onlinegdb here
Here is a code snippet:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
The above code does not work for any input. That is, it seems like it has crashed,though I could not understand where I'm mistaken. I guess the part with %lld in the printf has problems. But Ido not know how to fix it. I'm using code blocks.
Some expected outputs for corresponding inputs are as follows:
Input: 6 6 4
Output: 4
Input: 1000000000 1000000000 1
Output: 1000000000000000000(10^18).
APPEND:
So, I'm giving the link of the main problem below. The logic of my code seemed correct to me.
https://codeforces.com/contest/1/problem/A
As it's been pointed out in comments/answers the problem is that m and n is unsigned so your loops can only stop if m and n are a multiple of a.
If you look at the input 6 6 4 (i.e. m=6 and a=4), you can see that m first will change like m = 6 - 4 which leads to m being 2. So in the next loop m will change like m = 2 - 4 which should be -2 but since m is unsigned it will wrap to a very high positive number (i.e. UINT_MAX-1) and the loop will continue. That's not what you want.
To fix it I'll suggest you drop the while loops and simply do:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
One problem with this solution is that the sum (m + a - 1) may overflow (i.e. be greater than UINT_MAX) and therefore give wrong results. You can fix that by adding an overflow check before doing the sum.
Another way to protect against overflow could be:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
This code can then be reduced to:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
while(m>0){
m-=a;
p++;
}
will run until m is equal to 0, since it cannot be negative because it is unsigned. So if m is 4 and a is 6, then m will underflow and get the maximum value that m can hold minus 2. You should change the input variables to signed.
4386427 shows how you can use math to remove the loops completely, but for the more general case, you can do like this:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
Of course, you need to do the same thing for the second loop.
Another thing, check return value of scanf:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
Using an unsigned type isn't always the best choice to represent positive values, expecially when its modular behavior is not needed (and maybe forgotten, which leads to "unexpected" bugs). OP's use case requires an integral type capable of store a value of maximum 109, which is inside the range of a 32-bit signed integer (a long int to be sure).
As 4386427's answer shows, the while loops in OP's code may (and should) be avoided anyways, unless a "brute force" solution is somehow required (which is unlikely the case, given the origin of the question).
I'd use a function, though:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}
I have to print product of elements of array A mod 10^9+7,there should N elements in array and the constraints are 1<=N<=10^3 and 1<=A[i]<=10^3.
The code I wrote
#include<stdio.h>
int main()
{
int N, pro = 1;
scanf("%i", &N);
int arr[N];
for (int i = 0; i<N; i++) {
scanf("%i", &arr[i]);
pro = (pro*arr[i]) % (1000000007);
}
printf("%i", pro);
}
gave wrong answer but when I replaced int arr[N] to long int arr[N] and changed its precision specifier to %li it gave correct output.
My confusion is when the upper limit of array's elements is only 10^3 then why using long int worked and not just int.
i am using 64 bit windows OS and the inputs which i am giving are 3 digit numbers
as array elements for example 568,253 etc without any 0 in beginning.
Consider the case where N = 3 and A = [10^3,10^3,10^3].
After the second iteration, your product will be 10^9.
In the third iteration, your product will be (10^9 * 10^3) % 1000000007.
Before doing the modulo operation, the product would create integer overflow and hence the WA.
The problem may be the result of the expression (pro*arr[i]).
If we assume that the maximum value of pro is 1000000006 due to the modulo, and the maximum value of arr[i] is 10^3 as mentioned. So, this expression may take a value greater than a 32bit integer.
The other thing to look for is What the type of (pro * arr[i]) ? :
The compiler answers this question by look to the operands of the expression, and will set the return type, for integer, as the greater type of them.
If you set arr[] as an long int [] this expression will return a long integer, whereas, if you set arr[] as an int, it will return an int and so it'll be wrong :
int * int -> int
int * long int -> long int
I need to calculate a large number which has length about 9-10 digits. Msdn says that long long type has a range for:
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
But when i run this code i get a garbage value printed:
#include <stdio.h>
int main(){
int seed = 88888; //This will be always a 5 digit number so the square of
// it will be 9 or 10 digits length
long long square = seed * seed;
printf("square = %lld", square);
getchar();
return 0;
}
Output:
square = -688858048
seed is of type int. seed*seed will also be of type int. And 88888*88888 overflows the size of int. You then assign this garbage value to your long long.
Change the type of seed, or cast in you calculation:
long long square = ((long long) seed) * seed;