program.exe (C) has stopped working - c

I am extremely new to C and managed to compile this program, but the exe stops working upon running. I'm really not sure what's wrong.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define TINY 1.0e-20 // A small number.
void ludcmp(float a[3][3], int n, int *indx, float *d);
void lubksb(float a[3][3], int n, int *indx, float b[]) ;
int main(){
int i,n,*indx;
float *b,d;
float a[3][3] = {
{ 1.0, 2.0, 5.0},
{-1.0, 2.0, 3.0},
{ 6.0, 0.0, 1.0}
};
ludcmp(a,n,indx,&d);
lubksb(a,n,indx,b);
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
getchar();
return 0;
}
For those who were asking, the 2 functions ludcmp and lubksg are below. I got them from the numerical recipes textbook, but edited some lines to remove exclusive routines which I do not have. Specifically, they are the lines with malloc, printf, and free.
The original code came with all the loops starting with 1, which is why I also started my loop with 1. I have since changed all the loops to start from 0 instead, hopefully without introducing any new errors.
You can see the original code here:
https://github.com/saulwiggin/Numerical-Recipies-in-C/tree/master/Chapter2.Solution-of-Linear-Equations
Here is ludcmp:
void ludcmp(float a[3][3], int n, int *indx, float *d)
{
int i, imax, j, k;
float big, dum, sum, temp;
float *vv; // vv stores the implicit scaling of each row.
vv = (float *) malloc(n * sizeof(float));
*d=1.0;
for (i=0;i<n;i++) {
big=0.0;
for (j=0;j<n;j++)
if ((temp=fabs(a[i][j])) > big) big=temp;
if (big == 0.0)
{
printf("Singular matrix in routine ludcmp");
//free(vv);
}
// No nonzero largest element.
vv[i] = 1.0 / big; // Save the scaling.
}
// This is the loop over columns of Crout's method.
for (j=0;j<n;j++) {
for (i=0;i<j;i++) {
sum=a[i][j];
for (k=0;k<i;k++) sum -= a[i][k]*a[k][j];
a[i][j]=sum;
}
// Initialize for the search for largest pivot element.
big=0.0;
for (i=j;i<=n;i++) {
sum=a[i][j];
for (k=0;k<j;k++)
sum -= a[i][k]*a[k][j];
a[i][j]=sum;
if ( (dum=vv[i]*fabs(sum)) >= big) {
big=dum;
imax=i;
}
}
if (j != imax) {
for (k=0;k<n;k++) {
dum=a[imax][k];
a[imax][k]=a[j][k];
a[j][k]=dum;
}
*d = -(*d);
vv[imax]=vv[j];
}
indx[j]=imax;
if (a[j][j] == 0.0) a[j][j]=TINY;
if (j != n) {
dum=1.0/(a[j][j]);
for (i=j+1;i<n;i++) a[i][j] *= dum;
}
} // Go back for the next column in the reduction.
free(vv);
}
And lubksb:
void lubksb(float a[3][3],int n,int *indx,float b[])
{
int i,ii=0,ip,j;
float sum;
for (i=1;i<=n;i++) {
ip=indx[i];
sum=b[ip];
b[ip]=b[i];
if (ii)
for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
else if (sum) ii=i;
b[i]=sum;
}
for (i=n;i>=1;i--) {
sum=b[i];
for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
b[i]=sum/a[i][i];
}
}

This is a Two Dimensional Array and you are looping as it was just one. You should do something like:
for (int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
printf("%d %d: ", i+1, j+1);
}
}
Is bad practice to define the size of the array explicit. Try to use a constant.
And as said in the comments by #Marged:
In C arrays starts in 0

b is never assigned to anything valid when it's declared:
float *b,d;
At best, it's NULL or pointing to an invalid memory address:
I don't know what the lubksb function does:
lubksb(a,n,indx,b);
But b is clearly an invalid parameter since you never assign to it before calling this function.
And with this statement:
for(i = 1; i = 3; i++) {
printf("%.2f",b[i]);
}
As others have pointed out, array indices start at zero. But there's no evidence that b has a length of three anyway.

Related

Write a C function to evaluate the series // sin(x) = x-(x3 /3!)+(x5 /5!)-(x7 /7!)+... // up to 10 terms

#include <stdio.h>
#include<math.h>
int series(float,float);
int main()
{
float x,n,series_value;
printf("Enter the value of x: ");
scanf("%f",&x);
printf("\nEnter the value of n: ");
scanf("%f",&n);
series_value=series(x,n);
printf("\nValue of series sin (%.2f) is: %f\n",x,series_value);
return 0;
}
int series(float x,float n)
{
int i,sum=0,sign=-1;
int j,fact=1,p=1;
for (i=1; i<=(2*n)-1; i+=2)
{
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
sign=-1*sign;
sum=sum + sign*p/fact;
}
return (sum);
}
Output:
Enter the value of x: 5
Enter the value of n: 10
(lldb)
and this message
Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
![Thread 1 Queue : com.apple.main-thread (serial)
]1
Why is this message coming? and what is wrong in the program as answer is not coming right
There is a few problems with your code. As #PaulHankin said, when fact overflows and becoms zero, you will have a division by zero, and "weird things" happen.
Your factorial and power calculation is also wrong. You are recalculating it in each iteration of the outer loop without reseting fact and p first:
fact = 1; // You need to reset fact and p to its start value here
p = 1;
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
Your third problem is that for your function calculate the correct value for sin, which is not an integer value, you need to use float, or even better double, when calculating sum. So sum must be declared float, and the division p/fact must use float division. By also declaring p and fact as float, you will solve both the overflow issue, and use the correct division. Naturally your function must also return a float
float series(float x,float n)
{
int i,sign=-1;
int j,
float sum = 0;
float fact = 1;
float p = 1;
for (i=1; i<=(2*n)-1; i+=2)
{
fact = 1;
p = 1;
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
sign=-1*sign;
sum=sum + sign*p/fact;
}
return (sum);
}
This code still has a minor problem. By having an inner loop, it is slower than necessary. Since this probably is homework, I am not getting rid of that loop for you, just giving you a hint: You don't have to recalculate fact from scratch on each iteration of the outer loop, just try to find out how fact changes from one iteration to the next. The same goes for p.
//Series of Sinx
#include<stdio.h>
#include<math.h>
#define ACCURACY 0.0001
int factorial(int n);
int main()
{
float x,sum,term;
int i,power;
printf("Enter value of X: ");
scanf("%f",&x);
i=1;
power=3;
sum=x;
term=x;
while(term>=ACCURACY)
{
term = pow(x,power) / factorial(power);
if(i%2==1)
{
sum -= term;
}
else
{
sum += term;
}
power+=2;
i++;
}
printf("sin(%f) = %.6f\n",x,sum);
return 0;
}
int factorial(int n){
int i=n,fact=1;
for(i=1;i<=n;i++)
{
fact=fact*i;
}
return fact;
}
plenty bugs. To do not caclulate the fact values all the time they are in the lookup table
#include <stdio.h>
#include <math.h>
double series(double,int);
long long fact[] = { 1, 2, 6, 24,
120, 720, 5040, 40320,
362880, 3628800, 39916800, 479001600,
6227020800, 87178291200, };
double mypow(double x, unsigned p)
{
double result = x;
while(p && --p)
result *= x;
return result;
}
int main()
{
for(double x = 0; x <= M_PI + M_PI / 60; x += M_PI / 30)
printf("Value of series sin (%.2f) is: %f\n",x,series(x, 5));
fflush(stdout);
}
double series(double x,int n)
{
double sum = x;
int i,sign=1;
for (i=3; i<=(2*n)-1; i+=2)
{
sign=-1*sign;
sum += sign*(mypow(x, i)/fact[i -1]);
}
return (sum);
}
https://godbolt.org/z/U6dULN
maybe its due to floating-point exception as u have declared that the function should return int type value
int series(float,float);//hear
so u can try editing the return type of this function as float
Note:-also u need to change at function definition and the datatype of
int i,sum=0,sign=-1;
int j,fact=1,p=1;
to float as it is returning the value (sum) which should also be float

How to use a nested if else statements in a for loop in c

I'm having issues with my for statement. I'm trying to have a nested if else statement inside and I'm using pointers. I've tried everything and I've looked all over the internet. I've placed comments beside the lines with errors but if you see something else that's wrong please let me know. Thank you
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
void getinput(double*xptr, int*nptr)
{
int flag;
do
{
flag = TRUE;
printf("What is the value of x and the number of terms:");
scanf("%lf %i", xptr, nptr);
if (*nptr <= 0)
{
printf("The number of terms must be positive\n");
flag = FALSE;
}
}
while(flag == FALSE);
}
double sinHyper(double *xptr, int *nptr) {
int i;
double sum;
double ti;
i = 0;
ti = 0;
for (i = 0; i < *nptr; i = i+1)// I'm getting a Warning: comparioson between pointer and integer
{
if (i == 0)
{
sum = xptr;
} else {
ti = 2*i+1;
ti = ti*2*i;
ti = (xptr*xptr)/ti;// I'm getting a error: invalid operands to binary * (have 'double*' and 'double*')
sum = ti*sum;
}
}
return (sum);
}
void main() {
int n;
double x;
double sinhx;
getinput(&x, &n);
sinhx = sinHyper(&x, &n);
printf("For an x of %.0f with %i terms the sinh(x) is %f", x, n, sinhx);
return 0;
}
You forgot to dereference your pointers in several places.
The fact that this line compiles
sum = xptr;
should not mislead you: C lets you convert a pointer to a number with only a warning, while in most cases this is an error. This line should be
sum = *xptr;
It does not let you multiply pointers, so the expression where you square your pointer is an error:
(xptr*xptr)
You should either dereference the pointer twice, i.e. write
((*xptr)*(*xptr))
or make a separate variable for the current value of *xptr and use it instead:
const double x = *xptr;
ti = (x*x)/ti;
Note: This exercise should be purely theoretical, because sinHyper does not change *xptr or *nptr. Therefore, you should pass them as values, not as pointers:
double sinHyper(const double x, const int n) {
...
}
...
sinhx = sinHyper(x, n);

Creating n random points and creating quadrilaterals (stuck) C

I have this homework assignment and I am a bit stuck with it.
Create n random points, using these points create 2 quadrilaterals, which envelop the rest of the points, and compare the area of the 2 shapes.(not a graphical solution, purely mathematical)
I can not figure out how to connect my points or how to tell the computer which points to connect. I was thinking maybe finding the max and min X and Y could work but I didn't get further than that.
Thanks is advance!
void genp(int n,int** x,int** y);
void rectangle(int n,int** x,int** y);
void file(int n, int** x, int** y);
int main()
{
int n;
printf("Please specify number of points!\n");
scanf("%d", &n);
int *x;
int *y;
genp(n,&x,&y);
for (int i = 0; i < n; i++)
{
printf("x[%d]=%d\ty[%d]=%d\n", i, x[i], i, y[i]);
}
rectangle(n,&x,&y);
file(n,&x,&y);
free(x);
free(y);
return 0;
}
void genp(int n,int** x, int** y)
{
int r;
srand(time(NULL));
*x = (int*)malloc(n * sizeof(int));
*y = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
{
r = rand();
(*x)[i] = r;
r = rand();
(*y)[i] = r;
}
}
void rectangle(int n,int** x,int **y)
{
int maxlocx,maxlocy,maxx,maxy,minx,miny,minlocx,minlocy;
int zerox=*x[0];
int zeroy=*y[0];
for(int i=0;i<n;i++)
{
if ((*x)[i]>zerox)
{
maxx=(*x)[i];
maxlocx=i;
}
if ((*y)[i]>zeroy)
{
maxy=(*y)[i];
maxlocy=i;
}
}
for (int i=0;i<n;i++)
{
if ((*x)[i]<zerox)
{
minx=(*x)[i];
minlocx=i;
}
if ((*y)[i]<zeroy)
{
miny=(*y)[i];
minlocy=i;
}
}
printf("\nThe max x:%d, corresponding y:%d\n",maxx,(*y)[maxlocx]);
printf("\nThe max y:%d, corresponding x:%d\n",maxy,(*x)[maxlocy]);
printf("\nThe min x:%d, corresponding y:%d\n",minx,(*y)[minlocx]);
printf("\nThe min y:%d, corresponding x:%d\n",miny,(*x)[minlocy]);
int area=
}
void file(int n,int** x,int** y)
{
FILE *f;
f=fopen("data.txt","w");
fprintf(f,"n=%d\n",n);
for (int i=0;i<n;i++)
{
fprintf(f,"%d,%d\n",(*x)[i],(*y)[i]);
}
fclose(f);
}
I was thinking maybe finding the max and min X and Y could work but I didn't get further than that.
This sounds about right for me and was the first thing that I thought when reading that problem statement.
As for the 2nd quadrilateral maybe you could do something like trying to find a bounding rectangle with tilted axis instead of axis that are parellel to the X and Y axis. For example, with a tilt of 45 degrees the bounding box would look like this:
I can not figure out how to connect my points or how to tell the computer which points to connect.
I'm kind of getting the impression that you are trying to find the Convex Hull of your set of points. That would be a much harder problem than just finding a bounding box. (And it might not be a quadrilateral anyway)

What does #QNANO signify or mean in C?

#include<stdio.h>
#include<math.h>
int n;
struct vector
{
int dir[100];
};
int dot(struct vector v1, struct vector v2)
{
int dp,j;
dp=0;
for(j=0;j<n;j++)
{
dp = dp + (v1.dir[j]*v2.dir[j]);
}
return dp;
}
float cosine(int vdot, float v1mod, float v2mod)
{
float cos1, vdo = vdot;
cos1 = (vdot/(v1mod*v2mod));
return cos1;
}
float modul(struct vector v1)
{
int j;
float v1mod;
float deg = 0;
for(j=0; j<n; j++)
{
deg = deg + ((v1.dir[j])*(v1.dir[j]));
}
v1mod = sqrt(deg);
}
int main()
{
int j;
scanf("%d", &n);
struct vector v1;
struct vector v2;
for(j=0;j<n;j++)
{
scanf("%d", &v1.dir[j]);
}
for(j=0;j<n;j++)
{
printf("%d/", v1.dir[j]);
}
printf("\n");
for(j=0;j<n;j++)
{
scanf("%d", &v2.dir[j]);
}
for(j=0;j<n;j++)
{
printf("%d/", v2.dir[j]);
}
printf("\n");
int vdot;
float v1mod, v2mod, cos2;
vdot = dot(v1,v2);
printf("%d\n", vdot);
v1mod = modul(v1);
printf("%f\n", v1mod);
v2mod = modul(v2);
printf("%f\n", v2mod);
cos2 = cosine(vdot, v1mod, v2mod);
printf("cosine = %f\n", cos2);
}
When we compile the code, the output for cosine is showing "1.#QNANO.
I checked all the websites, but no where did I find the right reason for the occurrence of the
error.
Also can some one specify how many such more error types are there .
**The bug in the code is intentional.
The Q probably means it's a quiet not-a-number. The O might mean overflow.
What exact platform and compiler did you use?
So I was running a few codes and doing some experiments and came across this Error. (#QNANO)
The most valid explanation I could come up with is the data specifier mismatch i.e have a look at this simple code:
#include<stdio.h>
int main()
{
int a,c;
a = 2;
float b;
b = 3;
c = a*b;
printf("%f",c);
return 0;
}
The output of this simple code is -1 #QNANO, so I assume that as an integer variable was multiplied by a floating variable and the result was stored in an integer variable but when we print the value of c and we do that with %f, then the integer variable cannot be converted to float and hence the error throws up.

Selecting and analysing window of points in an array

Could someone please advise me on how to resolve this problem.
I have a function which performs a simple regression analysis on a sets of point contained in an array.
I have one array (pval) which contains all the data I want to perform regression analysis on.
This is how I want to implement this.
I get an average value for the first 7 elements of the array. This is what I call a 'ref_avg' in the programme.
I want to perform a regression analysis for every five elements of the array taking the first element of this array as the 'ref_avg'. That is in every step of the regression analysis I will have 6 points in the array.
e.g
For the 1st step the ref_avg as calculated below is 70.78. So the 1st step in the simple regression will contain these points
1st = {70.78,76.26,69.17,68.68,71.49,73.08},
The second step will contain the ref_avg as the 1st element and other elements starting from the second element in the original array
2nd = {70.78,69.17,68.68,71.49,73.08,72.99},
3rd = {70.78,68.68,71.49,73.08,72.99,70.36},
4th = {70.78,71.49,73.08,72.99,70.36,57.82} and so on until the end.
The regression function is also shown below.
I don't understand why the first 3 elements of the 'calcul' array have value 0.00 on the first step of the regression, 2 elements on the 2nd step,1 elements on the 3rd.
Also the last step of the regression function is printed 3 times.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
float pval[]={76.26,69.17,68.68,71.49,73.08,72.99,70.36,57.82,58.98,69.71,70.43,77.53,80.77,70.30,70.5,70.79,75.58,76.88,80.20,77.69,80.80,70.5,85.27,75.25};
int count,Nhour;
const int MAX_HOUR = 24;
float *calcul=NULL;
float *tab_time =NULL;
float ref_avg;
int size_hour=7;
float sum=0;
int length = Nhour+1;
float m;
float b;
calcul=(float*)calloc(MAX_HOUR,sizeof(calcul));
if (calcul==NULL)
{
printf(" error in buffer\n");
exit(EXIT_FAILURE);
}
tab_time= calloc(MAX_HOUR,sizeof(float));
/* Get the average of the first seven elements */
int i;
for (i=0;i<size_hour;i++)
{
sum += pval[i];
}
ref_avg = sum / size_hour;
count=0;
/* perform the regression analysis on 5 hours increment */
while(count<=MAX_HOUR)
{
++count;
Nhour=5;
int pass = -(Nhour-1);
int i=0;
for(i=0;i<Nhour+1;i++)
{
if(count<MAX_HOUR)
{
calcul[0]=ref_avg;
calcul[i] =pval[count+pass];
pass++;
}
printf("calc=%.2f\n",calcul[i]); // For debug only
tab_time[i]=i+1;
if(i==Nhour)
{
linear_regression(tab_time, calcul, length, &m, &b);
printf("Slope= %.2f\n", m);
}
}
}
free(calcul);
calcul=NULL;
free(tab_time);
tab_time=NULL;
return 0;
}
/* end of the main function */
/* This function is used to calculate the linear
regression as it was called above in the main function.
It compiles and runs very well, was just included for the
compilation and execution of the main function above where I have a problem. */
int linear_regression(const float *x, const float *y, const int n, float *beta1, float *beta0)
{
float sumx = 0,
sumy = 0,
sumx2 = 0,
sumxy = 0;
int i;
if (n <= 1) {
*beta1 = 0;
*beta0= 0;
printf("Not enough data for regression \n");
}
else
{
float variance;
for (i = 0; i < n; i++)
{
sumx += x[i];
sumy += y[i];
sumx2 += (x[i] * x[i]);
sumxy += (x[i] * y[i]);
}
variance = (sumx2 - ((sumx * sumx) / n));
if ( variance != 0) {
*beta1 = (sumxy - ((sumx * sumy) / n)) / variance;
*beta0 = (sumy - ((*beta1) * sumx)) / n;
}
else
{
*beta1 = 0;
*beta0 = 0;
}
}
return 0;
}
I think this code produces sane answers. The reference average quoted in the question seems to be wrong. The memory allocation is not needed. The value of MAX_HOUR was 24 but there were only 23 data values in the array. The indexing in building up the array to be regressed was bogus, referencing negative indexes in the pval array (and hence leading to erroneous results). The variable Nhour was referenced before it was initialized; the variable length was not correctly set. There wasn't good diagnostic printing.
The body of main() here is substantially rewritten; the editing on linear_regression() is much more nearly minimal. The code is more consistently laid out and white space has been used to make it easier to read. This version terminates the regression when there is no longer enough data left to fill the array with 5 values - it is not clear what the intended termination condition was.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void linear_regression(const float *x, const float *y, const int n,
float *beta1, float *beta0);
int main(void)
{
float pval[]={
76.26, 68.68, 71.49, 73.08, 72.99, 70.36, 57.82, 58.98,
69.71, 70.43, 77.53, 80.77, 70.30, 70.50, 70.79, 75.58,
76.88, 80.20, 77.69, 80.80, 70.50, 85.27, 75.25,
};
const int Nhour = 5;
const int MAX_HOUR = sizeof(pval)/sizeof(pval[0]);
const int size_hour = 7;
float ref_avg;
float sum = 0.0;
float m;
float b;
float calc_y[6];
float calc_x[6];
/* Get the average of the first seven elements */
for (int i = 0; i < size_hour; i++)
sum += pval[i];
ref_avg = sum / size_hour;
printf("ref avg = %5.2f\n", ref_avg); // JL
/* perform the regression analysis on 5 hours increment */
for (int pass = 0; pass <= MAX_HOUR - Nhour; pass++) // JL
{
calc_y[0] = ref_avg;
calc_x[0] = pass + 1;
printf("pass %d\ncalc_y[0] = %5.2f, calc_x[0] = %5.2f\n",
pass, calc_y[0], calc_x[0]);
for (int i = 1; i <= Nhour; i++)
{
int n = pass + i - 1;
calc_y[i] = pval[n];
calc_x[i] = pass + i + 1;
printf("calc_y[%d] = %5.2f, calc_x[%d] = %5.2f, n = %2d\n",
i, calc_y[i], i, calc_x[i], n);
}
linear_regression(calc_x, calc_y, Nhour+1, &m, &b);
printf("Slope= %5.2f, intercept = %5.2f\n", m, b);
}
return 0;
}
void linear_regression(const float *x, const float *y, const int n, float *beta1, float *beta0)
{
float sumx1 = 0.0;
float sumy1 = 0.0;
float sumx2 = 0.0;
float sumxy = 0.0;
assert(n > 1);
for (int i = 0; i < n; i++)
{
sumx1 += x[i];
sumy1 += y[i];
sumx2 += (x[i] * x[i]);
sumxy += (x[i] * y[i]);
}
float variance = (sumx2 - ((sumx1 * sumx1) / n));
if (variance != 0.0)
{
*beta1 = (sumxy - ((sumx1 * sumy1) / n)) / variance;
*beta0 = (sumy1 - ((*beta1) * sumx1)) / n;
}
else
{
*beta1 = 0.0;
*beta0 = 0.0;
}
}

Resources