So I have to make this formula "y = y / (3/17) - z + x / (a % 2) + PI" in C
I am having a problem with (a%2) as it is returning odd values. ie 1%2 = 0.000001
int assignment7()
{
#define PI 3.14
int a=0,amod2;
double Ny=0,y=0,z=0,x=0;
printf("Enter values for x,y,z and a: ");
scanf("%d%lf%lf%lf",&a,&y,&z,&x);
//printf("%d,%lf,%lf,%lf\n",a,y,z,x);
//amod2=1%2;
//printf("%lf",amod2);
Ny=y/(double)(3/17) - z+x / amod2 + PI;
printf("%lf\n",Ny);
When you say:
printf("%lf",amod2);
the compiler expects amod2 to be a "long float" (aka a double), but you defined it as:
int amod2;
Also your prompt says "x,y,z and a" but you read in the order "a,y,z,x":
printf("Enter values for x,y,z and a: ");
scanf("%d%lf%lf%lf",&a,&y,&z,&x);
that's awkward at best.
EDIT: cleaned up a bit and made some assumptions about order of operations:
#include <stdio.h>
#define PI 3.14
#define DIVSOR (3.0/17.0)
int assignment7 ( void );
int assignment7 ( void ) {
double x = 0.0;
double y = 0.0;
double z = 0.0;
int a = 0;
int amod2;
double Ny;
printf("Enter values for x,y,z and a: ");
scanf("%lf%lf%lf%d",&x,&y,&z,&a);
amod2 = a % 2;
Ny = (y / DIVSOR) - z + (x / amod2) + PI;
printf("%lf\n", Ny);
return 0;
}
int main ( void ) { return assignment7(); }
You don't say what inputs you are giving it, (a test case with inputs and the expected results would be super helpful), but I can point out that x / (a % 2) is going to be infinity when a is 2 or 4 or 6 or ...
Related
In this program, I'm trying to calculate the square root with the newton equation 1/2(x+a/x) just using integers. So if I repeat this equation at least 10 times, it should divide the number by 1000 and give an approximate value of the square root of a/1000. This is the code:
int main (){
int32_t a, x; //integers a and x
float root;
do{
scanf ("%d", &a); // get value of a from the user
if (a < 1000 ){ // if chosen number is less than 1000 the programm ends.
break;
}
x = ((float) a / 1000); //starting value of x is a / 1000;
for (int i = 0; i < 50;i++)
{
root = ((float) x * (float) x + a/1000) / ((float)2*x); // convert int to float //through casting
x = (float)root; // refresh the value of x to be the root of the last value.
}
printf ("%f\n", (float)root);
}while (1);
return 0;
}
so if I calculate the square root of 2000, it should give back the square root of 2(1.414..), but it just gives an approximate value: 1.50000
How can I correct this using integers and casting them with float?
thanks
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char * *argv, char * *envp) {
int32_t a, x; //integers a and x
float root;
do {
scanf ("%d", &a); // get value of a from the user
if (a < 1000) { // if chosen number is less than 1000 the program ends.
break;
}
x = (int32_t)((float) a / 1000.0f); //starting value of x is a / 1000;
for (int i = 0; i < 1000; i++) {
// Fixed formula based on (x+a/x)/2
root = ((float)x + (((float)a) / (float)x)) / 2.0f;
//Below, wrong old formula
//root = ((float) x * (float) x + a / 1000) / ((float) 2 * x); // convert int to float //through casting
x = (int32_t) root; // refresh the value of x to be the root of the last value.
}
printf ("%f\n", root);
} while (1);
return (EXIT_SUCCESS);
}
The iterates of x = (x + a / x) / 2 for a = 2000000 and x0 = 1000 (all integer variables) are 1500, 1416 and 1414. Then 200000000 gives 14142 and so on.
-use double precision
-use sqrt() and exponential function exp()
-use * to compute the square
-do not use pow()
I am getting values they are just not anything as to what I expected. I tried making them all signed but it didn't change anything and I've tried printing out with 12 decimal places and nothing seems to be working.I have linked the math library and defined it as well.
double normal(double x, double sigma, double mu)
{
double func = 1.0/(sigma * sqrt(2.0*M_PI));
double raise = 1.0/2.0*((x-mu)/sigma);
double func1 = func * exp(raise);
double comp_func = (func1 * func1);
return comp_func;
}
int main(void)
{
// create two constant variables for μ and σ
const double sigma, mu;
//create a variable for x - only dynamic variable in equation
unsigned int x;
//create a variable for N values of x to use for loop
int no_x;
//scaniing value into mu
printf("Enter mean u: ");
scanf("%lf", &mu);
//scanning value into sigma
printf("Enter standard deviation: ");
scanf("%lf", &sigma);
//if sigma = 0 then exit
if(sigma == 0)
{
printf("error you entered: 0");
exit(0);
}
//storing number of x values in no_x
printf("Number of x values: ");
scanf("%d", &no_x);
//the for loop where i am calling function normal N times
for(int i = 1; i <= no_x; i++)
{
//printing i for the counter in prompted x values
printf("x value %d : ", i);
// scanning in x
scanf("%lf", &x);
x = normal(x,sigma,mu);
printf("f(x) = : %lf.12", x);
printf("\n");
}
return 0;
}
C:>.\a.exe
Enter mean u: 3.489
Enter std dev s: 1.203
Number of x values: 3
x value 1: 3.4
f(X) = 0.330716549275
x value 2: -3.4
f(X) = 0.000000025104
x value 3: 4
f(X) = 0.303015189801
But this is what I am receiving
C:\Csource>a.exe
Enter mean u: 3.489
Enter standard deviation: 1.203
Number of x values: 3
x value 1 : 3.4
f(x) = : 15086080.000000
x value 2 : -3.4
f(x) = : 15086080.000000
x value 3 : 4
f(x) = : 1610612736.000000
Insert these lines:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
Change:
const double sigma, mu;
to:
double sigma, mu;
Change:
unsigned int x;
to:
double x;
Replace the definition of the normal function with:
double normal(double x, double sigma, double mu)
{
double func = 1.0/(sigma * sqrt(2.0*M_PI));
double t = (x-mu)/sigma;
return func * exp(-t*t/2);
}
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
#include<math.h>
#include<stdio.h>
#include <stdlib.h>
double normal(double x, double sigma, double mu)
{
double func = 1.0/(sigma * sqrt(2.0*M_PI));
double t = (x-mu)/sigma;
return func * exp((-0.5*t)* t);
}
I Finally got this code above working after tweaking with it literally all day lol, C math can be rather tricky, thank you for the help above as well.
Second part of Q: Then solve the integral between 0 and y of (x^2)(e^(-x^2))dx=0.1 for y using bracketing and bisection.
Here's what I have done so far:
#include <stdio.h>
#include <math.h>
double f(double x, double y);
int main(void) {
int i, steps;
double a, b, y, h, m, lower, upper, x, simp, val;
/*
* Integrate (x^2)(e^(-x^2)) from 0 to y
*/
steps = 20000;
a = 0;
b = y;
h= (b-a)/steps;
/*
* now apply Simpson's rule. Note that the steps should be even.
*/
simp = -f(a, y);
x = a;
for (i =0; i < steps; i += 2) {
simp += 2.0*f(x,y)+4.0*f(x+h, y);
x += 2*h;
}
simp += f(b, y);
simp *= h/3.0;
/*
* print out the answer
*/
printf("The integral from 0 to y with respect to x by Simpson's Rule is %f\n", simp);
/*
* Now we need to bracket and bisect to find y
*/
lower = 0;
/*
* Lower bound is from turning point
*/
upper = 100;
/*
*Upper value given.
*/
while (upper - lower > 10E-10){
m = (lower + upper)/2;
val = f(m, y);
if (val >=0)
upper = m;
if (val <=0)
lower = m;
}
m = (lower + upper)/2;
printf("The value for y is: %lf\n", m);
return 0;
}
double f(double x, double y) {
return pow(x,2)*exp(pow(-x,2))-0.1;
}
Output: The integral from 0 to y with respect to x by Simpson's Rule is -0.000000
The value for y is: 0.302120
It runs but doesn't do exactly what I need it to do. I need to be able to continue working with the integral once I've used 0 and y as the limits. I can't do this. Then continue on and solve for y. It gives me a value for y but is not the same one I get if i solve using online calculators. Also, the output gave zero for the integral even when I changed the equation to be integrated to x^2. Can anyone help explain in as simple terms as possible?
Say I have a high floating point number... 1345.23
I want to reduce it by 2*PI until it stays between -PI and +PI so I'd do:
#define PI 3.14159265358f
#define TWO_PI 6.28318530718f
float a = 1345.23f;
while (a > PI) a -= TWO_PI;
Do you know a fastest method?
With this code you will enter in the loop just 1 time (you can delate it adding just a more a -= TWO_PI
#include <stdio.h>
#define PI 3.14159265358f
#define TWO_PI 6.28318530718f
int main(void) {
float a = 1345.23f;
float b = 1345.23 - PI;
int c = b/TWO_PI;
a -= c*TWO_PI;
int i = 0;
while (a > PI){
a -= TWO_PI;
printf("%d",i++);
}
printf("\na : %f",a);
}
OUTPUT:
0
a : 0.628314
While your code will do the cicle :
214 times
BETTER CODE:
#include <stdio.h>
#define PI 3.14159265358f
#define TWO_PI 6.28318530718f
#define INV_TWO_PI 0.15915494309189533
int main(void) {
double a = 1345.23;
if(a > PI){
double b = a - PI; // you get the distance between a and PI
// int c = b/TWO_PI; // you get the integer part
int c = b * INV_TWO_PI; // the same as above using multiplication
a -= (c+1)*TWO_PI; // you just subtract c+1 times TWO_PI
// c+1 cause you want come in the range [-PI,PI]
}
}
Not the fastest, but the shortest code:
y = asin(sin(a));
Assuming that your code has to do with phase wrapping in radians, so that values between PI and TWO_PI can map between -PI and 0.0 a simple and fast solution would be:
double a = 1345.23;
double b = TWO_PI;
double c = (fmod(a,b) > PI ? fmod(a,b) - b : fmod(a,b));
After accept answer
To quickly reduce between -PI and PI, simply use remquof();
#include <math.h>
#include <stdio.h>
float reduce_radian(float x) {
static const float pi2 = 6.283185307179586476925286766559f;
int n;
return remquof(x, pi2, &n);
}
int main(void) {
printf("x % .10e\ty % .10e\n", 1e-30, reduce_radian(1e-30));
for (float x = 0.0f; x <= 4.0f; x += 1.0f) {
printf("x % .10f\ty % .10f\n", -x, reduce_radian(-x));
printf("x % .10f\ty % .10f\n", x, reduce_radian(x));
}
}
Output
x 1.0000000000e-30 y 1.0000000032e-30
x -0.0000000000 y -0.0000000000
x 0.0000000000 y 0.0000000000
x -1.0000000000 y -1.0000000000
x 1.0000000000 y 1.0000000000
x -2.0000000000 y -2.0000000000
x 2.0000000000 y 2.0000000000
x -3.0000000000 y -3.0000000000
x 3.0000000000 y 3.0000000000
x -4.0000000000 y 2.2831854820
x 4.0000000000 y -2.2831854820
To understand why this is not the best precise answer, is a deep subject.
See K.C. Ng's "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
I need to write my own asin() function without math.h library with the use of Taylor series. It works fine for numbers between <-0.98;0.98> but when I am close to limits it stops with 1604 iterations and therefore is inaccurate.
I don't know how to make it more accurete. Any suggestions are very appreciated!
The code is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EPS 0.000000000001
double my_arcsin(double x)
{
long double a, an, b, bn;
a = an = 1.0;
b = bn = 2.0;
long double n = 3.0;
double xn;
double xs = x;
double xp = x;
int iterace = 0;
xn = xs + (a/b) * (my_pow(xp,n) / n);
while (my_abs(xn - xs) >= EPS)
{
n += 2.0;
an += 2.0;
bn += 2.0;
a = a * an;
b = b * bn;
xs = xn;
xn = xs + (a/b) * (my_pow(xp,n) / n);
iterace++;
}
//printf("%d\n", iterace);
return xn;
}
int main(int argc, char* argv[])
{
double x = 0.0;
if (argc > 2)
x = strtod(argv[2], NULL);
if (strcmp(argv[1], "--asin") == 0)
{
if (x < -1 || x > 1)
printf("nan\n");
else
{
printf("%.10e\n", my_arcsin(x));
//printf("%.10e\n", asin(x));
}
return 0;
}
}
And also a short list of my values and expected ones:
My values Expected values my_asin(x)
5.2359877560e-01 5.2359877560e-01 0.5
1.5567132089e+00 1.5707963268e+00 1 //problem
1.4292568534e+00 1.4292568535e+00 0.99 //problem
1.1197695150e+00 1.1197695150e+00 0.9
1.2532358975e+00 1.2532358975e+00 0.95
Even though the convergence radius of the series expansion you are using is 1, therefore the series will eventually converge for -1 < x < 1, convergence is indeed painfully slow close to the limits of this interval. The solution is to somehow avoid these parts of the interval.
I suggest that you
use your original algorithm for |x| <= 1/sqrt(2),
use the identity arcsin(x) = pi/2 - arcsin(sqrt(1-x^2)) for 1/sqrt(2) < x <= 1.0,
use the identity arcsin(x) = -pi/2 + arcsin(sqrt(1-x^2)) for -1.0 <= x < -1/sqrt(2).
This way you can transform your input x into [-1/sqrt(2),1/sqrt(2)], where convergence is relatively fast.
PLEASE NOTICE: In this case I strongly recommend #Bence's method, since you can't expect a slowly convergent method with low data accuracy to obtain arbitrary precision.
However I'm willing to show you how to improve the result using your current algorithm.
The main problem is that a and b grows too fast and soon become inf (after merely about 150 iterations). Another similar problem is my_pow(xp,n) grows fast when n grows, however this doesn't matter much in this very case since we could assume the input data goes inside the range of [-1, 1].
So I've just changed the method you deal with a/b by introducing ab_ratio, see my edited code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EPS 0.000000000001
#include <math.h>
#define my_pow powl
#define my_abs fabsl
double my_arcsin(double x)
{
#if 0
long double a, an, b, bn;
a = an = 1.0;
b = bn = 2.0;
#endif
unsigned long _n = 0;
long double ab_ratio = 0.5;
long double n = 3.0;
long double xn;
long double xs = x;
long double xp = x;
int iterace = 0;
xn = xs + ab_ratio * (my_pow(xp,n) / n);
long double step = EPS;
#if 0
while (my_abs(step) >= EPS)
#else
while (1) /* manually stop it */
#endif
{
n += 2.0;
#if 0
an += 2.0;
bn += 2.0;
a = a * an;
b = b * bn;
#endif
_n += 1;
ab_ratio *= (1.0 + 2.0 * _n) / (2.0 + 2.0 * _n);
xs = xn;
step = ab_ratio * (my_pow(xp,n) / n);
xn = xs + step;
iterace++;
if (_n % 10000000 == 0)
printf("%lu %.10g %g %g %g %g\n", _n, (double)xn, (double)ab_ratio, (double)step, (double)xn, (double)my_pow(xp, n));
}
//printf("%d\n", iterace);
return xn;
}
int main(int argc, char* argv[])
{
double x = 0.0;
if (argc > 2)
x = strtod(argv[2], NULL);
if (strcmp(argv[1], "--asin") == 0)
{
if (x < -1 || x > 1)
printf("nan\n");
else
{
printf("%.10e\n", my_arcsin(x));
//printf("%.10e\n", asin(x));
}
return 0;
}
}
For 0.99 (and even 0.9999999) it soon gives correct results with more than 10 significant digits. However it gets slow when getting near to 1.
Actually the process has been running for nearly 12 minutes on my laptop calculating --asin 1, and the current result is 1.570786871 after 3560000000 iterations.
UPDATED: It's been 1h51min now and the result 1.570792915 and iteration count is 27340000000.