I was looking for a Extended Euclidean algorithm in C. I found the following piece of code:
int gcdExtended(int a, int b, int *x, int *y)
{
if (a == 0)
{
*x = 0;
*y = 1;
return b;
}
int x1, y1;
int gcd = gcdExtended(b%a, a, &x1, &y1);
*x = y1 - (b/a) * x1;
*y = x1;
return gcd;
}
so for gcdExtended(0,0) it will return: x=0 and y=1. But I saw some other versions of the algorithem which return x=0 and y=0. Both mathematically are true. But, is there a convention for this issue?
Related
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;
}
I have a general idea of how to do this, as you can see by the code I did below. The only problem I am having is finishing the interchange part. Basically, what I am trying to do is move the value of the lowest variable into the 1st variable, the second middle value to the 2nd variable, and the biggest to the 3rd variable.
I know I do this with the interchange and using temp somehow, but how would I complete that, because with three values temp would get overridden somehow. What am I missing? So basically a = 4.0, b = 7.0, c = 1.0, c (1.0) needs to go into a, a (4.0) needs to go into b, and b (7.0) needs to go into c.
Thanks!
#include <stdio.h>
void interchange(double * x, double * y, double * z);
int main(void)
{
double a = 4.0, b = 7.0, c = 1.0;
printf_s("Originally a = %d, b = %d, and c = %d.\n", a, b, c);
interchange(&a, &b, &c);
printf_s("Now, a = %d, b = %d, and c = %d.\n", a, b, c);
return 0;
}
void interchange(double * x, double * y, double * z)
{
double temp;
temp = *z;
*y = *z;
* = temp
// what am I missing here? I cant get my head around this above ^^^
}
Thanks for the guidance!
Something like:
void swap(double* first, double* last){
double temp = *first;
*first = *last;
*last = temp;
}
void interchange(double * x, double * y, double * z){
if(*x > *y) swap(x, y);
if(*y > *z) swap(y, z);
if(*x > *y) swap(x, y);
}
the simplest way is:
if (*x > *y) {
temp = *x; // store value of x
*x = *y; // overwrite x with y
*y = temp; // overwrite y with x (which is in temp)
}
// now we sure that x <= y
if (*y > *z) {
temp = *z;
*z = *y;
*y = temp;
}
// now we sure that x <= z and y <= z, but we don't know x/y relationships
if (*x > *y) {
temp = *x;
*x = *y;
*y = temp;
}
// now x <= y <= z
I'm using the bisection method to find the root of function in the domain from 70*10^9 to 250*10^9, but the output is always the upper bound, i.e 250*10^9. The function is a definite integral, I don't know where I did wrong. Thanks in advance.
#include <stdio.h>
#include <math.h>
double I = 0.0225, W = 50000, L = 25, Y = 12000;
double x, E;
typedef double(*DfD)(double);
double g(double), h(double);
double pow(double a, double b);
double g(double x){
return W*x*(x-L/2)-(Y*pow(x,3))/2;
}
double h(double x){
return Y*pow(x,3)/2;
}
double midpoint_int(DfD f, double x0, double x1, int n) {
int i;
double x, dx, sum = 0.0;
dx = (x1-x0)/n;
for (i = 0, x = x0 + dx/2; i < n; i ++, x +=dx)
sum += f(x);
return sum*dx;
}
double deflection (DfD f, double int1, double int2){
int1 = midpoint_int(g, L/2, L, 1000);
int2 = midpoint_int(h, 0, L/2, 1000);
return (int1 - int2)/(E*I)+0.5;
}
double bisection(DfD f, double a0, double a1, double tol ){
double middle;
for (;;){
middle = (a0 + a1)/2.0;
if (fabs(middle - a0) < tol)
return middle;
else if (f(middle) * f(a0) < 0.0)
a1 = middle;
else
a0 = middle;
}
}
int main (void){
double E;
E = bisection (deflection, 70*pow(10,9), 250*pow(10,9), 0.001);
printf("The optimal elastic modulus is %fPa.\n", E);
return;
}
This is a program to calculate a definite integral using numerical quadrature method (I don't know if this is the right translation):
#include <math.h>
#include <stdio.h>
float f(float x){
float y;
y = 4/(+x*x);
return y;
}
void quadra(float a, float b, float *Q, float *E, float f(float)){
float q1, q2, m, h, fa, fb;
h = b - a;
fa = f(a);
fb = f(b);
q1 = (fa+fb)*h/2.;
m = (a+b)/2.;
q2 = ( (fa+2*f(m)+fb) ) *h/4;
*Q = q2;
*E = fabs(q2-q1)/3;
}
void scambia(float *x, float *y) {
float z;
z = *x;
*x = *y;
*y = z;
return;
}
void sort(float x[], int n) {
int flag=1, k=n-1, i;
while (flag == 1 && k > 0) {
flag = 0;
for (i=0; i<k; i++) {
if (x[i]>x[i+1]) {
scambia(&x[i], &x[i+1]);
flag = 1;
}
}
k = k-1;
}
return;
}
int intautri(float A, float B, float TOL, int MAXFUN, float *Q, float *E, int *N, float FUN(float)){
void sort(float [], int);
void quadra(float, float, float*, float*, float(float));
float Q1,Q2,c,d,Iold,Eold,E0,E1,E2,alist[100],blist[100],qlist[100],elist[100];
int n, flag;
quadra(A, B, &Q1, &E0,FUN);
*N = 3;
n = 1;
alist[n] = A;
blist[n] = B;
qlist[n] = Q1;
elist[n] = E0;
*Q = Q1;
*E = E0;
if (*E<=TOL || *N>=MAXFUN){
flag = 1;
}else{
c = alist[n];
d = blist[n];
Iold = qlist[n];
Eold = elist[n];
n = n-1;
quadra(c, (c+d)/2, &Q1, &E1, FUN);
quadra((c+d)/2, d, &Q2, &E2, FUN);
*Q = *Q - Iold + Q1 + Q2;
*E = *E - Eold + E1 + E2;
*N = *N + 6;
intautri(A , B, TOL, MAXFUN, Q, E, N, FUN);
alist[n+1] = c;
blist[n+1] = (c+d)/2;
qlist[n+1] = Q1;
elist[n+1] = E1;
alist[n+2] = (c+d)/2;
blist[n+2] = d;
qlist[n+2] = Q2;
elist[n+2] = E2;
n = n+2;
sort(alist, n);
sort(blist, n);
sort(qlist, n);
sort(elist, n);
flag = 0;
}
;
return flag;
}
int main(){
int intautri(float, float, float, int, float *, float *, int*, float(float));
float TOL, MAXFUN, A, B,Q,E;
int N, J;
float f(float);
A = 0;
B = 1;
TOL = 0.0001;
MAXFUN = 200;
J = intautri(A, B, TOL, MAXFUN, &Q, &E, &N, f);
printf("%d\n", J);
printf("%d\n", N);
printf("%f\n", Q);
return 0;
}
Anyway I compile without problems that code, but when I run it "segmentation fault (core dumped)" appears on terminal. I know that error could depend by memory allocation but I don't understand what is wrong...can you help me??
You have an exit condition in intautri:
if (*E<=TOL || *N>=MAXFUN){
but in the beginning of the function you also have:
*N = 3;
This means that your second exit condition will never fire. Without attempting to understand the logic of the code, I believe that you should:
Initialize N in main().
Remove the *N = 3 assignment in intautri().
I'm trying to find minimum point of Gamma function by Golden Section method. But when I execute the program I get segmentation fault error. I think since I'm a newbie C user, the problem may be due to calling the function Min_Search_Golden_Section wrong. Here is my complete code. I can't find my mistake. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define A 12
#define sqrt5 2.236067977499789696
static int Stopping_Rule(double x0, double x1, double tolerance);
double sp_gamma(double z)
{
const int a = A;
static double c_space[A];
static double *c = NULL;
int k;
double accm;
if ( c == NULL ) {
double k1_factrl = 1.0; /* (k - 1)!*(-1)^k with 0!==1*/
c = c_space;
c[0] = sqrt(2.0*M_PI);
for(k=1; k < a; k++) {
c[k] = exp(a-k) * pow(a-k, k-0.5) / k1_factrl;
k1_factrl *= -k;
}
}
accm = c[0];
for(k=1; k < a; k++) {
accm += c[k] / ( z + k );
}
accm *= exp(-(z+a)) * pow(z+a, z+0.5); /* Gamma(z+1) */
return accm/z;
}
void Min_Search_Golden_Section( double (*f)(double), double* a, double *fa,
double* b, double* fb, double tolerance)
{
static const double lambda = 0.5 * (sqrt5 - 1.0);
static const double mu = 0.5 * (3.0 - sqrt5); // = 1 - lambda
double x1;
double x2;
double fx1;
double fx2;
// Find first two internal points and evaluate
// the function at the two internal points.
x1 = *b - lambda * (*b - *a);
x2 = *a + lambda * (*b - *a);
fx1 = f(x1);
fx2 = f(x2);
// Verify that the tolerance is an acceptable number
if (tolerance <= 0.0) tolerance = sqrt(DBL_EPSILON) * (*b - *a);
// Loop by exluding segments from current endpoints a, b
// to current internal points x1, x2 and then calculating
// a new internal point until the length of the interval
// is less than or equal to the tolerance.
while ( ! Stopping_Rule( *a, *b, tolerance) ) {
if (fx1 > fx2) {
*a = x1;
*fa = fx1;
if ( Stopping_Rule( *a, *b, tolerance) ) break;
x1 = x2;
fx1 = fx2;
x2 = *b - mu * (*b - *a);
fx2 = f(x2);
} else {
*b = x2;
*fb = fx2;
if ( Stopping_Rule( *a, *b, tolerance) ) break;
x2 = x1;
fx2 = fx1;
x1 = *a + mu * (*b - *a);
fx1 = f(x1);
}
}
return;
}
int main()
{
double x;
double a = 0.0, b = 4.0, fa = 0.00001, fb = 6.0;
double fx = sp_gamma(x);
Min_Search_Golden_Section( &fx, &a, &fa, &b, &fb, 0.0000001);
return 0;
}
static int Stopping_Rule(double x0, double x1, double tolerance)
{
double xm = 0.5 * fabs( x1 + x0 );
if ( xm <= 1.0 ) return ( fabs( x1 - x0 ) < tolerance ) ? 1 : 0;
return ( fabs( x1 - x0 ) < tolerance * xm ) ? 1 : 0;
}
You should be getting a compiler error. The first argument to Min_Search_Golden_Section should be a function pointer, but you pass the address of a variable instead.
When you get compiler errors, fix them - don't run the program and hope. :)
I guess you just meant to write:
Min_Search_Golden_Section( &sp_gamma, &a, &fa, &b, &fb, 0.0000001);