I am getting negative and positive result : when I enter(n value odd) odd term produces even or and even term produces odd value. I have already made function for factorial it works fine.
#include <stdio.h>
#include <math.h>
#define PI 3.14159f
int factorial(int n);
float sine(float , int);
int i;
void main(){
float degree;
float radian;
float result;
int n;
printf("Enter the angle in degree: ");
scanf("%f",°ree);
printf("Enter the iteration: ");
scanf("%d",&n);
radian = degree * PI / 180;
result = sine(radian,n);
printf("%d",factorial(n));
printf("\n");
printf("sin%.2f = %.3f",degree,result);
}
int factorial(int n)
{
if(n==0)
return 1;
else if (n==1)
return 1;
else
return (n*factorial(n-1));
}
float sine(float an, int n)
{
if (an==0)
return 0;
else if(n>=0)
if(n%2==1)
return (sine(an,n-2) - pow(an,n)/factorial(n)) * pow(-1,n);
else
return (sine(an,2*n-1) - pow(an,2*n+1)/factorial(2*n+1)) *-1 ;
}
float sine(float an, int n)
{
if (an == 0)
return 0;
The above condition returns 0 for sin(0) so it is of no use in rest of the recursion and it works fine.
else if(n >= 0)
if(n%2 == 1)
return (sine(an,n-2) - pow(an,n)/factorial(n)) * pow(-1,n);
else
return (sine(an,2*n-1) - pow(an,2*n+1)/factorial(2*n+1)) *-1 ;
Lets see where this part of your function goes, by substituting the value of n:
Suppose we are start with degree = 30 and number of iterations = 3
Then:
n = 3;
n is odd so function returns:
((sine(an, 3-2) - (float)pow(an, 3) / factorial(3)) * -1);
n = 1;
n is again odd so function returns:
((sine(an, 1-2) - (float)pow(an, 1) / factorial(1)) * -1);
n = -1;
This time n < 0 so if-else conditions are skipped and some garbage value is returned because you did not tell your program what to return at n = 0
So you need your sine-function to return a default value when n = 0
pow(-1,n) will always return -1 for odd values of n, and 1 for even values of n. So the sign of output of sine() function is not changing alternately like in the series.
Answering to the comment: Why the sign seems to change for odd or even,
In your code values of n are skipping the even numbers, instead of decreasing n by 1 per call, you are passing only odd numbers.
return (sine(an,n-2) - pow(an,n)/factorial(n)) * pow(-1,n);
so what you get in the end is a sum of negatives; And when you start with a even value of n like 2, then sine() is called with odd value of n the second time which is (2*n-1) which again returns a sum of negatives.
Heres what you can do:
float sine(float an, int n)
{
if (an == 0 || n == 0)
return 0; //to end the recursion when number of iterations are finished
else
return -1*pow(-1,n)*pow(an,2*n-1)/factorial(2*n-1) + sine(an, n - 1);
}
// `-1*pow(-1,n)` returns a negative term for even value of n, and postive term for odd value of n as required. You dont need separate if-else for that
Related
Here is a code to exponentiate a number to a given power:
#include <stdio.h>
int foo(int m, int k) {
if (k == 0) {
return 1;
} else if (k % 2 != 0) {
return m * foo(m, k - 1);
} else {
int p = foo(m, k / 2);
return p * p;
}
}
int main() {
int m, k;
while (scanf("%d %d", &m, &k) == 2) {
printf("%d\n", foo(m, k));
}
return 0;
}
How do I calculate the time complexity of the function foo?
I have been able to deduce that if k is a power of 2, the time complexity is O(log k).
But I am finding it difficult to calculate for other values of k. Any help would be much appreciated.
How do I calculate the time complexity of the function foo()?
I have been able to deduce that if k is a power of 2, the time complexity is O(logk).
First, I assume that the time needed for each function call is constant (this would for example not be the case if the time needed for a multiplication depends on the numbers being multiplied - which is the case on some computers).
We also assume that k>=1 (otherwise, the function will run endlessly unless there is an overflow).
Let's think the value k as a binary number:
If the rightmost bit is 0 (k%2!=0 is false), the number is shifted right by one bit (foo(m,k/2)) and the function is called recursively.
If the rightmost bit is 1 (k%2!=0 is true), the bit is changed to a 0 (foo(m,k-1)) and the function is called recursively. (We don't look at the case k=1, yet.)
This means that the function is called once for each bit and it is called once for each 1 bit. Or, in other words: It is called once for each 0 bit in the number and twice for each 1 bit.
If N is the number of function calls, n1 is the number of 1 bits and n0 is the number of 0 bits, we get the following formula:
N = n0 + 2*n1 + C
The constant C (C=(-1), if I didn't make a mistake) represents the case k=1 that we ignored up to now.
This means:
N = (n0 + n1) + n1 + C
And - because n0 + n1 = floor(log2(k)) + 1:
floor(log2(k)) + C <= N <= 2*floor(log2(k)) + C
As you can see, the time complexity is always O(log(k))
O(log(k))
Some modification added to output a statistics for spread sheet plot.
#include <stdio.h>
#include <math.h>
#ifndef TEST_NUM
#define TEST_NUM (100)
#endif
static size_t iter_count;
int foo(int m, int k) {
iter_count++;
if (k == 0) {
return 1;
} else if(k == 1) {
return m;
} else if (k % 2 != 0) {
return m * foo(m, k - 1);
} else {
int p = foo(m, k / 2);
return p * p;
}
}
int main() {
for (int i = 1; i < TEST_NUM; ++i) {
iter_count = 0;
int dummy_result = foo(1, i);
printf("%d, %zu, %f\n", i, iter_count, log2(i));
}
return 0;
}
Build it.
gcc t1.c -DTEST_NUM=10000
./a > output.csv
Now open the output file with a spread sheet program and plot the last two output columns.
For k positive, the function foo calls itself recursively p times if k is the p-th power of 2. If k is not a power of 2, the number of recursive calls is strictly inferior to 2 * p where p is the exponent of the largest power of 2 inferior to k.
Here is a demonstration:
let's expand the recursive call in the case k % 2 != 0:
int foo(int m, int k) {
if (k == 1) {
return m;
} else
if (k % 2 != 0) { /* 2 recursive calls */
// return m * foo(m, k - 1);
int p = foo(m, k / 2);
return m * p * p;
} else { /* 1 recursive call */
int p = foo(m, k / 2);
return p * p;
}
}
The total number of calls is floor(log2(k)) + bitcount(k), and bitcount(k) is by construction <= ceil(log2(k)).
There are no loops in the code and the time of each individual call is bounded by a constant, hence the overall time complexity of O(log k).
The number of times the function is called (recursively or not) per power call is proportional to the minimum number of bits in the exponent required to represent it in binary form.
Each time you enter in the function, it solves by reducing the number by one if the exponent is odd, OR reducing it to half if the exponent is even. This means that we will do n squares per significant bit in the number, and m more multiplications by the base for all the bits that are 1 in the exponent (which are, at most, n, so m < n) for a 32bit significant exponent (this is an exponent between 2^31 and 2^32 the routine will do between 32 and 64 products to get the result, and will reenter to itself a maximum of 64 times)
as in both cases the routine is tail-recursive, the code you post can be substituted with an iterative code in which a while loop is used to solve the problem.
int foo(int m, int k)
{
int prod = 1; /* last recursion foo(m, 0); */
int sq = m; /* squares */
while (k) {
if (k & 1) {
prod *= sq; /* foo(m, k); k odd */
}
k >>= 1;
sq *= sq;
}
return prod; /* return final product */
}
That's huge savings!!! (between 32 multiplications and 64 multiplications, to elevate something to 1,000,000,000 power)
#include <stdio.h>
#include <string.h>
int main() {
int start, end, i, sum = 0, temp, x, y, z;
puts("Please enter the starting number: ");
scanf("%d", &start);
temp = start;
x = start; y = start + 1;
puts("Please enter the last number till you want to add: ");
scanf("%d", &end);
for (i = start; i < end; i++) {
z = x + y;
x = z;
y = y + 1;
}
printf("The sum of the numbers starting from %d to %d is %d", temp, end, z);
}
Can anyone find what's wrong with this code?
It is working fine for less numbers but when I assign large numbers like 1 to 1000000, it doesn't work i.e. it returns strange values.
Case 1:
Please enter the starting number:
1
Please enter the last number till you want to add:
100
The sum of the numbers starting from 1 to 100 is 5050
But in this case -
Case 2:
Please enter the starting number:
1
Please enter the last number till you want to add:
1000000
The sum of the numbers starting from 1 to 1000000 is 1784293664
What's wrong in this case? Thanks in advance.
You are using int which only have value range -32,768 to 32,767 or -2,147,483,648 to 2,147,483,647 for 2 byte and 4 byte respectively.
You should use unsigned long long for your code which have a value range 0 to 18,446,744,073,709,551,615.
It's a case of data overflow.
For your example of computing from 1 to 1000000, the sum of consecutive numbers from 1 to x is x(x+1)/2, which is 500.000.500.000, a value largely above the range of an int (2.147.483 647).
Consider using long long int, and don't forget that regardless of the byte size of your variable up to a certain value you'll overflow anyway.
For large numbers you must use unsigned long long int instead of int. Here int means integer which is up to 3 or 4 digit numbers but when you enter 5 digit numbers or more digit numbers it gives you strange values.
Problem in finding sum of consecutive numbers
OP's code repeatedly adds and attempts a sum greater than INT_MAX leading to incorrect results.
Use a wider type for the computation of the sum such as long long or intmax_t.
Performance: Do not use a loop. The sum of integers [0...N] is N*(N+1)/2
Instead:
//for (i = start; i < end; i++) {
// z = x + y;
// x = z;
// y = y + 1;
//}
// Sum 0 to start
long long sum_start = ((long long) start + 1) * start / 2; // or (start + 1LL)*start/2;
// Sum 0 to end
long long sum_end = ((long long) end + 1) * end / 2;
// vvvv specifier change
printf("The sum of the numbers starting from %d to %d is %lld",
temp, end, sum_end - (sum_start - start));
The range of type int is not sufficient to represent the value of the sum for large values of start and stop (for example the sum for 0 to 65536 exceeds 2147483647). The variables x, y and z should be defined with type long long which is guaranteed to represent values up to 9223372036854775807 (9.22E18) or unsigned long up to 18446744073709551615 (1.84E19).
Furthermore your algorithm to compute the sum is convoluted, with unnecessary or unused intermediary variables. Simplicity is king!
Here is a modified version:
#include <stdio.h>
#include <string.h>
int main() {
int start, end, i;
long long sum;
puts("Please enter the starting number: ");
if (scanf("%d", &start) != 1)
return 1;
puts("Please enter the last number till you want to add: ");
if (scanf("%d", &end) != 1)
return 1;
sum = 0;
for (i = start; i <= end; i++) {
sum = sum + i;
}
printf("The sum of the numbers from %d to %d is %lld\n", start, end, sum);
return 0;
}
For positive start and stop values, there is a direct formula to compute the result. You could replace the for loop with this expression:
if (start <= stop) {
// take the sum of integers from 0 to stop: stop * (stop + 1) / 2
sum = (long long)stop * (stop + 1) / 2;
// subtract the sum of integers from 0 to start - 1: (start - 1) * start / 2
sum -= (long long)start * (start - 1) / 2;
} else {
sum = 0;
}
which simplifies as:
if (start <= stop) {
sum = ((long long)stop + start)(stop - start + 1) / 2;
} else {
sum = 0;
}
If start and/or stop can be negative, the sum can still be computed directly as:
if (start <= stop) {
// take the sum of integers from 0 to stop - start:
sum = (long long)(start - stop) * ((long long)stop - start + 1) / 2;
// add the initial value (stop - start + 1) times
sum += ((long long)stop - start + 1) * start;
} else {
sum = 0;
}
Which simplifies as:
if (start <= stop) {
sum = ((long long)stop + start)((long long)stop - start + 1) / 2;
} else {
sum = 0;
}
Sorry, but don't you know the following way to compute the sum?
long sum_from_a_to_b(long a, long b)
{
int n;
int acc = 0;
for (n = a; n <= b; n++)
acc += n;
return acc;
}
by the way, there's a better formula, which requires no loop:
#include <assert.h>
/* assumed that a <= b */
long sum_from_a_to_b(long a, long b)
{
assert(a <= b);
return b*(b + 1)/2 - a*(a - 1)/2;
}
In the second case, you have used a number that is greater than the allowed range for integer data type(it's from -32768 to 32767 for a 16-bit architecture and from -2,147,483,648 to 2,147,483,647 for a 32-bit architecture.) and that's why it leads to integer overflow issue. To fix this problem, you could use other bigger data types such as long int or long long int but I recommend you use their unsigned data types i.e unsigned long int or unsigned long long int if you're not going to use negative numbers because the range of unsigned data types begins from 0.
Problem statement :
Given a 32-bit signed integer, reverse digits of an integer.
Note: Assume we are dealing with an environment that could only store
integers within the 32-bit signed integer range: [ −2^31, 2^31 − 1]. For
the purpose of this problem, assume that your function returns 0 when
the reversed integer overflows.
I'm trying to implement the recursive function reverseRec(), It's working for smaller values but it's a mess for the edge cases.
int reverseRec(int x)
{
if(abs(x)<=9)
{
return x;
}
else
{
return reverseRec(x/10) + ((x%10)*(pow(10, (floor(log10(abs(x)))))));
}
}
I've implemented non recursive function which is working just fine :
int reverse(int x)
{
long long val = 0;
do{
val = val*10 + (x%10);
x /= 10;
}while(x);
return (val < INT_MIN || val > INT_MAX) ? 0 : val;
}
Here I use variable val of long long type to check the result with MAX and MIN of signed int type but the description of the problem specifically mentioned that we need to deal within the range of 32-bit integer, although somehow it got accepted but I'm just curious If there is a way to implement a recursive function using only int datatype ?
One more thing even if I consider using long long I'm failing to implement it in the recursive function reverseRec().
If there is a way to implement a recursive function using only int datatype ?
(and) returns 0 when the reversed integer overflows
Yes.
For such +/- problems, I like to fold the int values to one side and negate as needed. The folding to one side (- or +) simplifies overflow detection as only a single side needs testing
I prefer folding to the negative side as there are more negatives, than positives. (With 32-bit int, really didn't make any difference for this problem.)
As code forms the reversed value, test if the following r * 10 + least_digit may overflow before doing it.
An int only recursive solution to reverse an int. Overflow returns 0.
#include <limits.h>
#include <stdio.h>
static int reverse_recurse(int i, int r) {
if (i) {
int least_digit = i % 10;
if (r <= INT_MIN / 10 && (r < INT_MIN / 10 || least_digit < INT_MIN % 10)) {
return 1; /// Overflow indication
}
r = reverse_recurse(i / 10, r * 10 + least_digit);
}
return r;
}
// Reverse an int, overflow returns 0
int reverse_int(int i) {
// Proceed with negative values, they have more range than + side
int r = reverse_recurse(i > 0 ? -i : i, 0);
if (r > 0) {
return 0;
}
if (i > 0) {
if (r < -INT_MAX) {
return 0;
}
r = -r;
}
return r;
}
Test
int main(void) {
int t[] = {0, 1, 42, 1234567890, 1234567892, INT_MAX, INT_MIN};
for (unsigned i = 0; i < sizeof t / sizeof t[0]; i++) {
printf("%11d %11d\n", t[i], reverse_int(t[i]));
if (t[i] != INT_MIN) {
printf("%11d %11d\n", -t[i], reverse_int(-t[i]));
}
}
}
Output
0 0
0 0
1 1
-1 -1
42 24
-42 -24
1234567890 987654321
-1234567890 -987654321
1234567892 0
-1234567892 0
2147483647 0
-2147483647 0
-2147483648 0
You could add a second parameter:
int reverseRec(int x, int reversed)
{
if(x == 0)
{
return reversed;
}
else
{
return reverseRec(x/10, reversed * 10 + x%10);
}
}
And call the function passing the 0 for the second parameter. If you want negative numbers you can check the sign before and pass the absolute value to this function.
In trying to learn C programming I programed this question and get some correct results and some incorrect. I don't see the reason for the difference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h> // requires adding link to math -lm as in: gcc b.c -lm -o q11
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0) // if done returns value
{
return startValue;
}
int temp = startValue % 10; // gets units digit
int newStart = (startValue -temp)/10; // computes new starting value after removing one digit
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal); // calls itself recursively until done
}
int main()
{
int x, decimalP, startValue;
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
if (x > 214748364)
{
printf("Input number to be reversed \n Please note number must be less than 214748364 :");
scanf("%d", &x);
}
decimalP = round(log10(x)); // computes the number of powers of 10 - 0 being units etc.
startValue = ReverseInt(x, decimalP); // calls function with number to be reversed and powers of 10
printf("\n reverse of %d is %d \n", x, startValue);
}
Output is: reverse of 1234 is 4321 but then reverse of 4321 is 12340
It's late and nothing better does not come into my mind. No float calculations. Of course, integer has to be big enough to accommodate the result. Otherwise it is an UB.
int rev(int x, int partial, int *max)
{
int result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
int reverse(int x)
{
int max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d", reverse(-456789));
}
https://godbolt.org/z/M1eezf
unsigned rev(unsigned x, unsigned partial, unsigned *max)
{
unsigned result;
if(x / partial < 10)
{
*max = partial;
return (x % 10) * partial;
}
result = rev(x, partial * 10, max) + (x / (*max / partial) % 10) * partial;
return result;
}
unsigned reverse(unsigned x)
{
unsigned max;
return rev(x, 1, &max);
}
int main(void){
printf("%u", reverse(123456));
}
when using long long to store the result all possible integers can be reversed
long long rev(int x, long long partial, long long *max)
{
long long result;
if(x / partial < 10 && (int)(x / partial) > -10)
{
*max = partial;
return abs(x % 10) * partial;
}
result = rev(x, partial * 10, max) + abs(((x / (int)(*max / partial)) % 10) * partial);
return result;
}
long long reverse(int x)
{
long long max;
return rev(x, 1, &max) * ((x < 0) ? -1 : 1);
}
int main(void){
printf("%d reversed %lld\n", INT_MIN, reverse(INT_MIN));
printf("%d reversed %lld\n", INT_MAX, reverse(INT_MAX));
}
https://godbolt.org/z/KMfbxz
I am assuming by reversing an integer you mean turning 129 to 921 or 120 to 21.
You need an initial method to initialize your recursive function.
Your recursive function must figure out how many decimal places your integer uses. This can be found by using log base 10 with the value and then converting the result to a integer.
log10 (103) approx. 2.04 => 2
Modulus the initial value by 10 to get the ones place and store it in a variable called temp
Subtract the ones place from the initial value and store that in a variable called newStart.
divide this value by 10
Subtract one from the decimal place and store in another variable called newDecimal.
Return the ones place times 10 to the power of the decimal place and add it to the function where the initial value is newStart and the decimalPlace is newDecimal.
#include <stdio.h>
#include <math.h>
int ReverseInt(int startValue, int decimalPlace);
int main()
{
int i = -54;
int positive = i < 0? i*-1 : i;
double d = log10(positive);
int output = ReverseInt(positive,(int)d);
int correctedOutput = i < 0? output*-1 : output;
printf("%d \n",correctedOutput);
return 0;
}
int ReverseInt(int startValue, int decimalPlace)
{
if(decimalPlace == 0)
{
return startValue;
}
int temp = startValue % 10;
int newStart = (startValue -temp)/10;
int newDecimal = decimalPlace -1;
int value = temp*pow(10,decimalPlace);
return value + ReverseInt(newStart,newDecimal);
}
I am trying to make a program in C that uses a recursive function to calculate the factorial for Euler's number, and sends that data to main where the recursive function is to stop once two successive values have a difference of 0.0000001, however i cannot seem to get my program to work as it keeps returning -inf. Anyone know what im doing wrong?
EDIT: With this current code i can get the program to print result as 0.5, but it does not increment n past 2.
#include <stdio.h>
double factorial(double n);
int main ()
{
double n;
double sum = 0;
double last;
double result = 0;
for (n = 1; result <=0.0000001; n++)
{
last = sum;
sum = factorial(n);
result = (1 / last) - (1 / sum);
printf("result is %lf\n", result);
}
printf("result is %lf\n", result); // troubleshooting
return 0;
}
double factorial(double n)
{
if (n > 0)
return ( n * factorial(n-1));
else
return 1;
}
On the first iteration in main:
sum == 0
last = sum; => last == 0
result = (1 / sum) - (1 / last); => 1 / last == 1 / 0 == inf
Then you subtract (1 / last), which is inf, from (1 / sum), and get negative infinity.
Also, the loop never iterates more than once because you return result on the very first iteration.
I am new to recursion so I am trying to write a simple program that adds to the nth number of the series 1/n. So if the user enters n = 4, the program will add 1 + 1/2 + 1/3 + 1/4. My program keeps outputting that the sum of the series is 0. Can someone please explain what I am doing wrong? I'd appreciate the help. Here is my code:
#include <stdio.h>
double sum(double n);
int main() {
double n;
double total;
printf("Enter a positive integer greater than 0: ");
scanf("%lf", &n);
total = sum(n);
printf("Sum: %lf", total);
return 0;
}
double sum(double n) {
if (n == 1)
return 1;
else
return ((1 / n) + sum(n - 1));
}
The problem is in the definition of this function:
double sum(int n) {
if (n == 1)
return 1;
else
return ((1 / n) + sum(n - 1));
}
n is int so 1/n will be always evaluated as int since both 1 and n are integers. Thus 1/n is always 0 for each n>1.
The solution would be to define n as double :
double sum(double n) {
if (n <= 1.0)
return 1.0;
else
return ((1.0 / n) + sum(n - 1.0));
}
Check your base case. sum(1) should return 1.
Also, an int divided by an int returns an int. Use a floating point number in your division.
It should be
double sum(double n) {
if (n == 1)
return 1.0;
else
return ((1.0 / n) + sum(n - 1));
}
1/n will always return 0 since 'n' acts as an integer value and not a float value even though the datatype is double as the value assigned to it is of type integer.