I am stuck up with this problem.
I get double values in some variables which are as follows:
a = 0.76271469999999997000
b = 0.66698279999999999000
c = 0.34262199999999998000
I need to round these to
rounded_a = 0.762714700000000
rounded_b = 0.666982800000000
rounded_c = 0.342622000000000
How should I go about doing this?
#include <stdio.h>
#include <math.h>
double round_n(double x, int n){
double wk;
wk = pow(10.0, (double)n);
return round(x * wk)/wk;//c99 function
}
int main(void){
double a, b, c;
a = 0.76271469999999997000;
b = 0.66698279999999999000;
c = 0.34262199999999998000;
a = round_n(a, 7);
b = round_n(b, 7);
c = round_n(c, 7);
printf("a=%.8lf\nb=%.8lf\nc=%.8lf", a, b, c);
return 0;
}
Here is the code I use:
int64_t __pow10_arr[18] = { 1l, 10l, 100l, 1000l, 10000l, 100000l,
1000000l, 10000000, 100000000l, 1000000000l, 10000000000l, 100000000000l,
1000000000000l, 10000000000000l, 100000000000000l, 1000000000000000l, 10000000000000000l, 100000000000000000l };
double roundToNfractions ( double val, int n )
{
if (n<0 || n >= ( sizeof (__pow10_arr)/ sizeof (int64_t) ) ) {
// log error however you wish to
return val;
}
val *= __pow10_arr[n];
val += 0.5;
val = (uint64_t) val;
val /= __pow10_arr[n];
return val;
}
Related
i have a C code that finds the solution of a function using the methode of bisection and Newton Raphson, and i want to compare the results using graphs ( i am asked to do so in matlab as it's a school project ), but i have no idea how.
here's my code :
`
#include <stdio.h>
#include <math.h>
#include<stdio.h>
#include<math.h>
float F0 (float V)
{
float J0 = 1e-15;
float n = 0.68;
float V0 = 0.025;
int E = 1;
int R = 100;
return (E-V-R*J0*(exp(n*V/V0)-1));
}
float F1 (float V)
{
float J0 = 1e-15;
float n = 0.68;
float V0 = 0.025;
int E = 1;
int R = 100;
return (-1-n*R*J0/V0*exp(n*V/V0));
}
void Dichotomie (float *V, float a, float b, int *itr)
{
*V=(a+b)/2;
++(*itr);
printf("Iteration no. %3d V = %7.5f\n", *itr, *V);
}
void Newton(int itr, int maxmitr, float h, float V0, float V1, float err)
{
for (itr=1; itr<=maxmitr; itr++)
{
h=F0(V0)/F1(V0);
V1=V0-h;
printf("Iteration no. %3d, V = %9.6f\n", itr, V1);
if (fabs(h) < 2*err)
{
printf("After %3d iterations, root = %8.6f\n", itr, V1);
return;
}
V0=V1;
}
printf(" The required solution does not converge or iterations are insufficient\n");
return;
}
int main ()
{
float J0 = 1e-15;
float n = 0.68;
float V0 = 0.025;
int E = 1;
int R = 100;
int itr = 0, maxmitr;
float V, a, b, err, V1;
float h;
a = 0;
b = 1;
err = 0.000001;
maxmitr = 100;
Newton(itr, maxmitr,h,V0,V1,err);
Dichotomie (&V, a, b, &itr);
do
{
if (F0(a)*F0(V) < 0)
b=V;
else
a=V;
Dichotomie (&V1, a, b, &itr);
if (fabs(V1-V) < 2*err)
{
printf("After %d iterations, root = %6.6f\n", itr, V1);
return 0;
}
V=V1;
}
while (itr < maxmitr);
printf("The solution does not converge or iterations are not sufficient");
return 1;
}
`
I read some documentations about this in the Matlab website, and i found that there is a function block in Simulink to be used, but i have no idea how Simulink works.
I am trying to calculate value of sin(x) in C but I am getting black screen in code:block after execution, its taking long for compilation and execution.
#include<stdio.h>
float mult(float x, int m, int i) {
float a = x;
if (i == m) {
return x;
} else {
i++;
a = a * mult(x, m, i);
return a;
}
}
int fact(int m) {
printf("%d! ", m); fflush(stdout);
int b;
if (m == 1) {
return 1;
} else {
b = m * fact(m - 1);
return b;
}
}
float term(float x, int m) {
float a = 0, b = 0, c = 0;
int i = 0;
a = mult(x, m, i);
b = fact(m);
c = a / (1.0 * b);
return c;
}
float sinof(float x, int m, int n) {
float b = 0;
if (m >= 10) {
return (0);
} else {
printf("......%d ", m); fflush(stdout);
b = term(x, m);
m = m + 2;
n = -n;
b = b + (n * sinof(x, m, n));
return b;
}
}
int main() {
float x = 0, sin = 0;
int m = 1, n = 1;
printf("Enter the angle in radians:");
scanf("%f", &x);
sin = sinof(x, m, n);
printf("%f", sin);
}
I hope the logic is correct.
m is odd. Below fails to stop recursion.
if(m==10){ // Never true
return(0);
} else{
b=term(x,m);
m=m+2;n=-n; // ***********
b=b+(n*sinof(x,m,n));
return b;
}
I recommend OP get own code working first. There are various other issues.
For a simplified recursive sine(), mouse over to see.
static double my_sin_helper(double xx, double term, unsigned n) {
if (term + 1.0 == 1.0) {
return term;
}
return term - my_sin_helper(xx, xx *term / ((n + 1) * (n + 2)), n + 2);
}
// valid for [-pi/2 + pi/2]
double my_sin_primary(double x) {
return x * my_sin_helper(x * x, 1.0, 1);
}
I have an assignment to code a program to calculate cos(x) through the Maclaurin approximation. However I must use a function for the cos(x) and another one to calculate the exponentials that go on the denominators inside the cos(x) function. I think most of this is right, but I'm probably missing on something and I can't figure out what.
#include<stdio.h>
#include <stdlib.h>
#include <math.h>
int fat(int);
float cosx(float);
int main()
{
float x1;
/* Original code: **x1 = x1 * 3.14159 / 180;** `transforms the value to radians` */
x1 = x1 * 3.14159 / 180; /* transforms the value to radians */
printf("Insert number:\n");
scanf("%f", &x1);
printf("Cosine of %f = %f", x1, cosx(x1));
return 0;
}
int fat(int y)
{
int n, fat = 1;
for(n = 1; n <= y; n++)
{
fat = fat * n;
}
return fat;
}
float cosx(float x)
{
int i=1, a = 2, b, c = 1, e;
float cos;
while(i < 20)
{
b = c * (pow(x,a)) / e;
cos = 1 - b;
a += 2;
e = fat(a);
c *= -1;
i++;
}
return cos;
}
If I input 0 it returns -2147483648.000000, which is clearly wrong.
First error is uninitialized variable x1, and right after that you have use:
int x1; // <<< uninitiated variable;
**x1 = x1 * 3.14159 / 180;** `transforms the value to radians
this will produce random value, you should put
int x = 0; // or some other value of your choice
In my opinion you should move x1 = x1 * 3.14159/100; after scanf("%d", x1).
Than again uninitiated value e before use.
int i=1, a = 2, b, c = 1, e;
...
b = c * (pow(x,a)) / e;
...
than you have in the line b = c * pow(x,a) where you go out of range of int variable potentially. If e = 1, x = 2 and a > 31 you are out of range for b. Another problem is pow(x,a) is rising much faster than `e. thus you get bigger and bigger values thus you are getting another overflow. And here is the code that works:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
long double fact(int);
long double cosx(double);
long double my_pow (double b, int e);
int main()
{
double x1 = 45.00;
printf("Insert number:\n");
scanf("%lf", &x1);
x1 = x1 * 3.14159 / 180; // ** `transforms the value to radians`
printf("Cosine of %f = %.10LF", x1, cosx(x1));
return 0;
}
long double fact(int y)
{
int n;
double fact = 1;
for(n = 1; n <= y; n++)
{
fact *= n;
}
return fact;
}
long double cosx(double x)
{
int a = 2, c = -1;
long i = 0, lim = 500;
long double cos = 1;
long double b = 0, e = 0;
while(i < lim) {
e = fact(a);
b = c * my_pow(x,a);
cos += b/e;
// printf ("%le %le %le\n", e, b, cos);
a += 2;
c *= -1;
i++;
}
return cos;
}
long double my_pow (double b, int e) {
long double pow = 1;
for (;e > 0; --e, pow *= b)
;
return pow;
}
So lets say the input is 45392.56, the output has to be 49352.56.
How can i program this in C?
#include <stdio.h>
#include <stdlib.h>
int dotPos(char arr[]) {
int i = 0;
while (arr[++i] != '.');
return i;
}
int main() {
double d = 45392.56;
int MAX = 100;
char arr[MAX];
sprintf(arr, "%f", d);
if (dotPos(arr) > 3) {
char aux = arr[1];
arr[1] = arr[3];
arr[3] = aux;
}
d = atof(arr);
printf("%.2f\n", d);
}
Output:
49352.56
Convert the number to a character array. Look at the sprintf function.
Swap the positions of the characters.
Convert the character array to double. Look at the atof function.
Avoiding conversion to string and back, take the integral part of the number, find the two values in position 1 and 3 (in decimal notation), and compute the value to add or substract to/from the original double.
this is (a-b) *pow(10,hipos) - (a-b) * pow(10,lopos)
#include <stdio.h>
long finddiff(unsigned long val, unsigned lpos, unsigned rpos);
int main(void) {
double d = 45392.56;
unsigned long u;
long dif;
u = d;
dif = finddiff(u,3,1);
d += dif;
printf("%.2f\n", d);
return 0;
}
long finddiff(unsigned long val, unsigned lpos, unsigned rpos)
{
long res;
unsigned pos, ll, rr;
if (lpos < rpos) return finddiff(val, rpos,lpos);
for (pos=0; pos < rpos; pos++) { val /= 10; }
rr = val %10;
for (; pos < lpos; pos++) { val /= 10; }
ll = val %10;
// fprintf(stderr, "%u,%u\n", ll,rr);
res = rr-ll;
for (; pos > rpos; pos--) { res *= 10; }
res -= rr-ll;
for (; pos > 0; pos--) { res *= 10; }
// fprintf(stderr, "%u,%u,%ld\n", ll,rr, res);
if (ll > rr) res = -res;
else if (rr > ll) {;}
else res = 0;
return res;
}
BTW: this will fail miserably for values whose integer part is larger than the maximum log int, eg 6.3E23 .
For negative numbers some additional logic should be added.
I am tyring to make velocity Verlet method, by using C language.
I thought I made it good. However, there pops up 'Segmentation fault(core dumped)' whenever, I increase the size of the vector or array, x and y.
For the size n equal and less than 1e3, it's fine, but at the point of n = 1e4, the program gets error.
Please anybody help me on this.
Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double verlet(double t, double x)
{
double E = 0.252;
double B = 0.052;
double a = M_PI/2;
return -sin(x) + E*cos(t) + B*cos(2*t+a);
}
double pverlet(double(*f)(double, double), double dt, double t, double x, double y)
{
return x + dt*( y + (dt/2)*f(t, x));
}
double vverlet(double(*g)(double, double), double dt, double t, double x, double y)
{
return y + (dt/2) * g(t, x);
}
int main(void)
{
int i;
double t;
int n = 1e4;
double ti = 0, tf = 1e5, dt = (tf-ti)/n;
double *x = (double *) malloc(sizeof(double)*n);
double *y = (double *) malloc(sizeof(double)*2*n);
if (x == NULL)
{
printf("error allocating memory!\n");
return 1;
}
if (y == NULL)
{
printf("error allocating memory!\n");
return 1;
}
for (y[0] = 0, i = 1; i <2*n; i++)
{
y[i] = vverlet(verlet, dt, ti + dt*(i-1), x[i-1], y[i-1]);
}
for (x[0] = 0, i = 1; i < n; i++)
{
x[i] = pverlet(verlet, dt, ti + dt*(i-1), x[i-1], y[2*(i-1)]);
}
for (i = 0; i < n; i++)
{
t = ti + dt * i;
printf("%e %e %e\n", t, x[i], y[2*i]);
}
return 0;
free(x);
free(y);
}
for (y[0] = 0, i = 1; i <2*n; i++)
{
y[i] = vverlet(verlet, dt, ti + dt*(i-1), x[i-1], y[i-1]);
}
x is defined from 0 to n-1.