C - Simple division (1/n) results in strange answers - c

I'm trying to calculate a simple approximation to an integral by dividing it up into a step function, easy stuff. The problem starts when I simply try to do a division. Here is my code:
double integrand(int a, double div, int n) {
int i;
double sum, val;
val = 1.0/div;
for(i = 0; i < div; i++) {
sum = sum + (pow(i*val, n)/(i*val + a)) * val;
}
return sum;
}
Here div is actually an integer, I tried bringing it into the integrand function originally as an integer and typecasting it to a double inside the function, with the same result. When I debug the code, div can be say, 100, yet val will return something ludicrous like -7.2008557565654656e+304. As far as I'm aware the rest of the code is correct, but I just cannot figure this out, what's going on?!

You never initialized sum:
double sum = 0, val;
Right now, you're using it in your calculation with an uninitialized value, and hence getting some garbage results.

First initialize sum and then use it. Otherwise it will invoke undefined behavior.

Related

Why does my approximation of Exponential using Taylor Series expansion return "inf"?

This is my homework:
I haven't tried to write the part of Natural Logarithm because I can't solve the part of Exponential.
This is the the approximations of Exponential in C using Taylor Series expansion I wrote.
However, it returns inf. What did I do wrong?
#include <stdio.h>
// Returns approximate value of e^x
// using sum of first n terms of Taylor Series
float exponential(int n, float x)
{
float sum = 1.0f; // initialize sum of series
for (int a = n; a >= 0; ++a ) {
while (x * sum / a < 0.00001) {
break;
}
sum = 1 + x * sum / a;
return sum;
}
}
int main()
{
int n = 0;
float x = 1.0f;
printf("e^x = %.5f", exponential(n, x));
return 0;
}
With How do I ask and answer homework questions? in mind, I will give you a few things to have a careful look at.
From comment by Spektre:
from a quick look you are dividing by zero in while (x * sum / a < 0.00001) during first iteration of for loop as a=n and you called the function with n=0 ... also your code does not match the expansion for e^x at all
Have a look at the for loop:
for (int a = n; a >= 0; ++a )
What is the first value of a? The second? The third?
Keep in mind that the values are determined by ++a.
When will that loop end? It is determined by a >= 0. When is that false?
What is this loop doing?
while (x * sum / a < 0.00001) {
break;
}
I suspect that you programmed "English to C", as "do the outer loop while ...", which is practically from the assignment.
But the loop does something else. Apart from risking the division by 0 mentioned above, if the condition is true it will stay true and cause an endless loop, which then however is immediatly canceled in the first iteration.
The head of your function float exponential(int n, float x) expects n as a parameter. In main you init it with 0. I suspect you are unclear about where that value n is supposed to come from. In fact it is unknown. It is more a result of the calculation than an input.
You are supposed to add up until something happens.
You do not actually ever need the value of n. This means that your for loop is meaningless. The inner loop (though currently pointless) is much closer to your goal.
I will leave it at this for now. Try to use this input.
Feel free to edit the code in your question with improvements.
(Normally that is not appreciated, but in case of homework dialog questions I am fine with it.)
Your current implementation attempt is quite a bit off. Therefore I will describe how you should approach calculating such a series as given in your quesiton.
Let's look at your first formula:
You need to sum up terms e(n) = x^n / n!
To check with your series: 1 == x^0 / 0! - x == x^1 / 1! - ...
To calculate these terms, you need a simple rule how to get from e(n) to e(n+1). Looking at the formula above we see that you can use this rule:
e(n+1) = e(n) * x / (n+1)
Then you need to create a loop around that and sum up all the bits & pieces.
You are clearly not supposed to calculate x^n/n! from scratch in each iteration.
Your condition to stop the loop is when you reach the limit of 1e-5. The limit is for the new e(n+1), not for the sum.
For the other formulas you can use the same approach to find a rule how to calculate the single terms.
You might need to multiply the value by -1 in each step or do something like *x*n/(n+1) instead of *x/(n+1) etc.
Maybe you need to add some check if the formula is supposed to converge. Then maybe print some error message. This part is not clear in your question.
As this is homework, I only point into the direction and leave the implementation work to you.
If you have problems with implementation, I suggest to create a new question.
#include <stdio.h>
int main() {
float power;
printf("Enter the power of e\n");
scanf("%f", &power);
float ans = 1;
float temp = 1;
int i = 1;
while ((temp * power) / i >= 0.00001) {
temp = (temp * power) / i;
ans = ans + temp;
i++;
}
printf("%.5f", ans);
return 0;
}
I think I solved the problem
But the part about Natural Log is not solved, I will try.

Reversing a 5-digit number is the prog. and it is giving a wrong output

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int i,a,n,r;
n=12345;
r=0;
for(i=4;i>=0;i--)
{
a=n%10;
n=n/10;
r=r+a*pow(10,i);
}
printf("%d",r);
return 0;
}
Current output - 54320
Expected output - 54321
Please advise on what I may change in my code to reflect the correct output.
The pow function returns a value of type double. Because this is a floating point type, the result it returns will not always be exact.
What's happening in this case is that on the last iteration of the loop pow(10, 0) returns a value slightly less than 1. This results in the right hand side of r=r+a*pow(10,i); to similarly be slightly less than 54321. When this value is then assigned to r, which is of type int, it gets truncated.
Rather than using the pow function here, use the following:
r=r*10+a;
This shifts the current digits in r over by 1, then adds the newest digit to the end. Also, rather than using a for loop, use while (n>0) instead. Then it doesn't matter how many digits you have.
while (n>0)
{
a=n%10;
n=n/10;
r=r*10+a;
}
Here is a simplified version of your algorithm:
void reverse_digits(int a) {
int b = 0;
while (a > 0) {
b = b * 10 + a % 10;
a /= 10;
}
printf("%d\n", b);
}
As for converting to character arrays as mentioned in the comments it's worth to notice that the convertion function will do similar arithmetic operations in order to convert the integer to character array, so doing the reversing using integers seems more convenient.

error: expected expression before ‘float’

I would like to find all the primes within 100. Here is my codes.
// Find all the prime number within 100.
#include<stdio.h>
#include<math.h>
#include<stdbool.h>
int main() {
int i,n;
int j = 0;
for ( n = 2; n <= 100; ++n) {
bool isPrime = true;
for (i = 2; i <= sqrt(float(n)); ++i) {
if(n % i == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
++j;
printf("%d is a prime number\n",n);
}
}
printf("The total number of prime number within 100 is %d\n",j);
return 0;
}
When compile it, there is one error.
prime.c:14:8: error: expected expression before ‘float’
m = float(n);
^
Could anyone help solve this problem? Thanks.
You're using the wrong syntax when casting (you're using one of C++'s many styles of casting, but for C there is only one way). Change:
sqrt(float(n))
to
sqrt((float)n)
Note however that sqrt takes a double, so strictly speaking this should be:
sqrt((double)n)
Note also that the cast is not necessary, and you can just write:
sqrt(n)
Change this
sqrt(float(n))
to this
sqrt((float)n)
You want to cast n to float.
You should use this function:
float sqrtf (float x);
which in C99 receives a float as an argument. Otherwise, it would be better to cast into double (if you use sqrt()).
sqrt-ref
What you have written:
float(n)
is like saying that float is a name of a function and you pass to it the parameter n.
Notice, that in your case, you don't need casting, since it's going to be performed automatically (to float if you use sqrtf() or to double if you use sqrt()).
Other notes, irrelevant with your syntax error.
Why not start the loop from 3 and increase the counter by two? If you think about it, this will faster and will produce the same results. If you want to test yourself, check my example here.
Also, what I had found pretty exciting when I was searching for primes, is the sieve of Eratosthene's (Κόσκινο του Ερατοσθένη) . Here is an example of it.
If you want to cast n to a float, use (float)n.
Just do:
sqrt(n);
You'll be having the exam same result as the casting for your case.

Multiply each element of an array by a number in C

I'm trying to optimize some of my code in C, which is a lot bigger than the snippet below. Coming from Python, I wonder whether you can simply multiply an entire array by a number like I do below.
Evidently, it does not work the way I do it below. Is there any other way that achieves the same thing, or do I have to step through the entire array as in the for loop?
void main()
{
int i;
float data[] = {1.,2.,3.,4.,5.};
//this fails
data *= 5.0;
//this works
for(i = 0; i < 5; i++) data[i] *= 5.0;
}
There is no short-cut you have to step through each element of the array.
Note however that in your example, you may achieve a speedup by using int rather than float for both your data and multiplier.
If you want to, you can do what you want through BLAS, Basic Linear Algebra Subprograms, which is optimised. This is not in the C standard, it is a package which you have to install yourself.
Sample code to achieve what you want:
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main () {
int limit =10;
float *a = calloc( limit, sizeof(float));
for ( int i = 0; i < limit ; i++){
a[i] = i;
}
cblas_sscal( limit , 0.5f, a, 1);
for ( int i = 0; i < limit ; i++){
printf("%3f, " , a[i]);
}
printf("\n");
}
The names of the functions is not obvious, but reading the guidelines you might start to guess what BLAS functions does. sscal() can be split into s for single precision and scal for scale, which means that this function works on floats. The same function for double precision is called dscal().
If you need to scale a vector with a constant and adding it to another, BLAS got a function for that too:
saxpy()
s a x p y
float a*x + y
y[i] += a*x
As you might guess there is a daxpy() too which works on doubles.
I'm afraid that, in C, you will have to use for(i = 0; i < 5; i++) data[i] *= 5.0;.
Python allows for so many more "shortcuts"; however, in C, you have to access each element and then manipulate those values.
Using the for-loop would be the shortest way to accomplish what you're trying to do to the array.
EDIT: If you have a large amount of data, there are more efficient (in terms of running time) ways to multiply 5 to each value. Check out loop tiling, for example.
data *= 5.0;
Here data is address of array which is constant.
if you want to multiply the first value in that array then use * operator as below.
*data *= 5.0;

Assigning to the real or imaginary part of a complex number in C

I need to work on complex to extract imaginary roots of polynomial using Newton's method.
I'm getting an error, so I broke the code down to simple problem to see what's wrong. When I try to compile it it returns an error:
warning: target of assignment not really an lvalue; this will be a hard error in the future
Also I would like to know if there is anyway I can display the whole complex number without going with creal and cimag.
#include<stdio.h>
#include<complex.h>
int main()
{
double complex z1 = 2 + 3*I;
creal(z1) = 5;
cimag(z1) = 10;
printf("%.2f +%.2f *i \n", creal(z1), cimag(z1));
return 0;
}
The problem is these lines:
creal(z1) = 5;
cimag(z1) = 10;
creal and cimag return doubles. You cannot assign to a functions return value. You can assign the return value of a function to another variable like double real = creal(z1).

Resources