The below returns too few arguments in the int main section on the fp and newton lines.
Can you explain this?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double f(double a, double b, double c, double x)
{
return pow(x,3)+a*pow(x,2)+b*x+c;
}
double fp(double a, double b, double c, double x)
{
return 3*pow(x,2)+(2*a*x)+b+0*c;
}
double newton(double a, double b, double c, double x)
{
return x - (f(a,b,c,x)/fp(a,b,c,x));
}
int main()
{
double a,b,c,x1,x2;
int i;
char *input = getenv("QUERY_STRING");
sscanf(input, "coeff1=%lf &coeff2=%lf &coeff3=%lf &x=%lf", &a, &b, &c, &x1);
if (fp(x1)==0.0)
{
printf("No convergence.\n");
return 0;
}
for (i=0;i<100;i++)
{
x2=newton(x1);
if (fabs(x1-x2)<= pow(10,-10)) break;
x1=x2;
}
printf("iteration = %d\n", i);
printf("x= %lf\n", x1);
return 0;
}
Just what the error says! You haven't passed enough arguments:
This prototype:
fp(double a, double b, double c, double x) {
means you need to pass four arguments, like:
fp(x1, what, about, these);
The same goes for newton.
Also, regarding if (fp(x1)==0.0) - While floating point zero values can be compared with each other (zero is excatly zero), remember that floating-point on computers is not exact. For that reason, you should always compare against some epsilon value:
#define EPSILON 0.0001 // salt to taste
#define ABS(x) ( ((x)<0) ? -(x) : x )
#define FP_EQUALS(x,y) (ABS(x-y) < EPSILON)
//if (d == 0.0) {
if (FP_EQUALS(d, 0.0)) {
// d is "zero"
}
//if (a == b) {
if (FP_EQUALS(a, b) {
Related
I was writing a C program. This C program has to compute the solutions of a quadratic equation. The problem is that debugger showed me this kind of errors: "E0147", and "C22371".
this is my program:
delta.c:
#include "delta.h"
#include "math.h"
double delta(double a, double b, double c) {
double delta = 0;
double power = pow(b, b);
delta = power - (4 * a * c);
return delta;
}
delta.h:
#if !defined DELTA_H
#define DELTA_H
extern double delta(double a, double b, double c);
#endif /* DELTA_H */
solutions.c:
#include "delta.h"
#include "solutions.h"
#include "math.h"
double solutions (double a, double b, double c, double* x1, double* x2) {
double checking_the_delta = 0;
checking_the_delta = delta(a, b, c);
if (checking_the_delta == 0) {
return 1;
}
else if (checking_the_delta >= 0) {
double tmp = delta(a, b, c);
double square_root = sqrt(tmp);
*x1 = (-b + square_root) / 2;
*x2 = (-b - square_root) / 2;
}
else
return 0;
}
solutions.h:
#if !defined SOLUTIONS_H
#define SOLUTIONS_H
extern solutions(double a, double b, double c, double* x1, double*
x2);
#endif /* SOLUTIONS_H */
and finally, the main.c:
#include "solutions.h"
#include "delta.h"
int main(void) {
solutions(...);
return 0;
}
the problem is in this line: "double solutions (double a, double b, double c, double* x1, double* x2)". the debugger said this declaration is incompatible with the declaration in the header file. Moreover, it said that "solutions redefinition: different basic types".
I'm completely lost, I've written the declarations again but debugger keeps showing me these two errors.
extern solutions(double a, double b, double c, double* x1, double* x2); fails to specify the return type of solutions. Typically, it will default to int, for reasons related to the history of C.
Then this is incompatible with double solutions (double a, double b, double c, double* x1, double* x2) because the latter declares the return type to be double.
Fix the declarations so they declare the same return type in both place: You might insert double after extern in the header declaration. However, it looks like the function is intended to return the number of distinct solutions. In that case, you may want to make the return type int in both places, and insert return 2; in the code that processes two solutions.
For starters the function solutions returns nothing in case when checking_the_delta > 0 though the function return type is not void.
double solutions (double a, double b, double c, double* x1, double* x2) {
double checking_the_delta = 0;
checking_the_delta = delta(a, b, c);
if (checking_the_delta == 0) {
return 1;
}
else if (checking_the_delta >= 0) {
double tmp = delta(a, b, c);
double square_root = sqrt(tmp);
*x1 = (-b + square_root) / 2;
*x2 = (-b - square_root) / 2;
}
else
return 0;
}
Also this declaration
double tmp = delta(a, b, c);
is redundant because the variable checking_the_delta already contains the result of the function call delta(a, b, c)
checking_the_delta = delta(a, b, c);
Secondly in the function declaration in the header you forgot to specify the return type double as in the function definition
extern soluzioni(double a, double b, double c, double* x1, double*
x2);
Pay attention to that the function actually returns an integer instead of a double value. So maybe you need to specify the return type int.
I have created some code that has multiple functions, and when an X value is entered it outputs a line that has computed the number for the given X value and h value that has been declared. However, in the terminal it only outputs one line of each value, and I need to implement some type of iterative structure that varies h from 10^-1 to 10^-8. Here is the code:
#include <stdio.h>
#include <math.h>
int main()
{
double u(double x)
{
return(pow(x,3.0));
}
double dudx(double x)
{
return(3.0 * pow(x,2.0));
}
double fdiff(double x, double h)
{
return((u(x+h) - u(x))/h);
}
double bdiff(double x, double h)
{
return((u(x) - u(x-h))/h);
}
double cdiff(double x, double h)
{
return((u(x+h)-u(x-h))/(2*h));
}
double fderr(double x, double h)
{
return(fabs(fdiff(x,h)-dudx(x)));
}
double bderr(double x, double h)
{
return(fabs(bdiff(x,h)-dudx(x)));
}
double cderr(double x, double h)
{
return(fabs(cdiff(x,h)-dudx(x)));
}
double x;
double h=1.0 * pow(10,-1.0);
printf("Enter an Integer ");
scanf("%lf",&x);
printf("u(x): %lf du/dx: %lf fd: %lf bd: %lf cd: %lf fderr: %lf bderr: %lf cderr: %lf\n", u(x), dudx(x), fdiff(x,h), bdiff(x,h), cdiff(x,h), fderr(x,h), bderr(x,h), cderr(x,h));
}
I'm pretty sure I have to use some type of for loop around this area:
double h=1.0 * pow(10,-1.0);
But, I do not know how to implement it! So to reiterate, how do I create an iterative structure that starts with an h value of 10^-1 and ends with 10^-8?
Thank you in advance!
I'm fairly new to coding and am currently learning C. In class I was given an assignment to write a program that calculates the hypotenuse of the triangle by using our own functions. However, there seems to be something wrong with the code that I have written.
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y, double z);
int main(void) {
double side1, side2, side3, counter;
side3 = 1;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf_s("%d %d", &side1, &side2);
printf("%.2f\n", hypotenuse(side1, side2, side3));
}
return 0;
}
double hypotenuse(double x, double y, double z) {
x *= x;
y *= y;
z = sqrt(x + y);
return z;
}
My instructor said that we're allowed to use the square root function sqrt of the math library. The main errors that I'm facing are:
1) side3 is not defined (This is why I just arbitrarily set it to 1, but is there some other way to prevent this error from happening?)
2) If I, for example, inputted 3 and 4 as side1 and side2, then side3 should be 5. However, the printed result is an absurdly long number.
Thank you for the help! Any words of advice are appreciated.
You don't need side3 variable - it is not used in calculation. And you function hypotenuse returns the result, so you can directly output the result of sqrt.
I use Ubuntu Linux and write it this way. Please look if you like it.
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y) {
double z = sqrt(x * x + y * y);
return z;
}
int main(void) {
double b1, b2, counter;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf("%lf %lf", &b1, &b2);
printf("%.2f\n", hypotenuse(b1, b2));
}
return 0;
}
Test
$ ./a.out
Enter values for two sides: 1 1.73
2.00
OP's code has some problems:
Key problem: Code should have generated a compiler warning as scanf() is directed to treat &side1 as an int *. Turn on all compiler warnings to save you time. Code used "%d" rather than the matching "%lf" to read a double. Also the return value should be checked to validate input.
double side1, side2, side3, counter;
...
// scanf_s("%d %d", &side1, &side2);
if (scanf_s("%lf %lf", &side1, &side2) != 2) puts("Input error");
size3 is not needed. Call hypotenuse() with 2 arguments. #ghostprgmr
// printf("%.2f\n", hypotenuse(side1, side2, side3));
printf("%.2f\n", hypotenuse(side1, side2));
// double hypotenuse(double x, double y, double z) {
double hypotenuse(double x, double y) {
double z = ...
Minor: Code used "%.2f" to print the value of the hypotenuse. This may be OK with select input values to OP's code, but is a poor choice, in general. If input values are vary small like 0.001 and 0.002, the output will print rounded value of 0.00. With very large values, the result will show many non-important digits as OP found with 130899030500194208680850288727868915862901750748094271410143232.00.
For development and debugging, consider using "%e" ,"%g" or "%a" to see a relevant double.
Note that x * x + y * y is prone to over/under flow, even when mathematically sqrt(x * x + y * y) is in the double range. That is one advantage of the standard function hypot(x,y) as it usually handles those edge cases well.
As a reference for anyone viewing this question:
You don't need to write your own function. Standard C provides functions to calculate the hypotnuse:
7.12.7.3 The hypot functions
Synopsis
#include <math.h>
double hypot(double x, double y);
float hypotf(float x, float y);
long double hypotl(long double x, long double y);
Note that you likely need to link with -lm, though that's not listed explicitly in the function documentation in the C standard nor the latest POSIX documentation. It might be documented elsewhere in the standards.
(Link to C11 [draft] standard - likely to be much longer-lived.)
Use correct format specifiers!
Format Specifier for double is not %d! Rest is fine.
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y, double z);
int main(void) {
double side1, side2, side3, counter;
side3 = 1;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf("%lf %lf", &side1, &side2);
printf("%.2f\n", hypotenuse(side1, side2, side3));
}
return 0;
}
double hypotenuse(double x, double y, double z) {
x *= x;
y *= y;
z = sqrt(x + y);
return z;
}
Also you could modify it to this:
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y);
int main(void) {
double side1, side2, counter;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf("%lf %lf", &side1, &side2);
printf("%.2f\n", hypotenuse(side1, side2));
}
return 0;
}
double hypotenuse(double x, double y) {
x *= x;
y *= y;
return sqrt(x + y);
}
I want to write a program that calculates expontiation using the Gauss' algorithm but if give input etc base=2,exp=50 i get as a result 0.0000.
#include<stdio.h>
float fastpower(int a,int b);
main()
{
int base,exp;
printf("Base:\n");
scanf("%d",&base);
printf("Exp:\n");
scanf("%d",&exp);
fastpower(base,exp);
system("pause");
}
float fastpower(int a,int b)
{
double result=1;
while (b>0)
{
if (b%2!=0)
result=result*a;
b=(b/2);
a=a*a;
}
printf("result is %lf\n",result);
}
Declare a as long (int64):
/*
compute a**b
*/
/* double fastpower(double a, int b) is even more better */
double fastpower(long a, int b) { /* double is more natural here: double result */
double result = 1.0;
while (b > 0) {
if (b % 2 != 0)
result *= a;
b /= 2;
a *= a; /* <- a is long to prevent overflow here */
}
/* You'd rather not output in functions */
printf("result is %lf\n", result);
return result; /* do not forget to return the result*/
}
But long could do overflow as well (e.g. 10**50); in this case use double for a
I have written a small piece of code to calculate quadratic equations, but if the discriminant is negative, i wanted it to write that there are no real numerical values for this quadratic equation.
To make this happen, I had to call a function with a fourth parameter of 0, which i think , i have no idea why, would be a bad programming practice ? Is it the case or am i just being too picky of my code ? Thank you. (The reason I'm asking this is because i dont want to pick up some bad habits early on in my programming 'career').
Here's the code.
#include <stdio.h>
#include <math.h>
#include <string.h>
double quadratic_equation(double a, double b, double c, double d);
int main(void)
{
char command[20];
int i;
printf("Enter your command: ");
fgets(command, 20, stdin);
for (i = 0; i < 20; i++) {
if (command[i] == '\n') {
command[i] = '\0';
break;
}
}
if (strcmp(command, "quadratic equation") == 0) {
double a, b, c, x;
printf("Enter A: ");
scanf("%lf", &a);
printf("Enter B: ");
scanf("%lf", &b);
printf("Enter C: ");
scanf("%lf", &c);
x = quadratic_equation(a, b, c, 0); // THIS PIECE HERE MIGHT BE BAD PRACITCE ?
if (x == 0) {
printf("There are no real numerical values to this quadratic equation.");
}
else {
printf("------------\n");
printf("x1 = %.2f\n", quadratic_equation(a, b, c, 1));
printf("x2 = %.2f", quadratic_equation(a, b, c, -1));
}
}
return 0;
}
double quadratic_equation(double a, double b, double c, double d) {
double discriminant, x, insideroot;
insideroot = ((b*b) - (4*a*c));
if (insideroot < 0) {
return 0;
}
discriminant = sqrt(insideroot);
x = (-b + (d * discriminant)) / (2 * a);
return x;
}
Thank you very much for your help :d !
This certainly is bad practice. Since the roots of a formula a, b, and c an be any double you do need some sort of passing.
I would suggest a parameter that is a pointer to an int. If the pointer is NULL it is ignored, otherwise it will be set to 1 or 0 depending whether a real root exists:
double quadratic_equation(double a, double b, double c, int *root_exists) {
double discriminant;
discriminant = ((b*b) - (4*a*c));
if (discriminant < 0) {
if (root_exists != NULL) *root_exists = 0;
return 0.0;
}
x = (-b + sqrt(discriminant)) / (2 * a);
if (root_exists != NULL) *root_exists = 1;
return x;
}
A more rigorous approach is this:
typedef struct {
int num_roots;
double roots[2];
} quadratic_roots_t;
quadratic_roots_t quadratic_equation(double a, double b, double c) {
quadratic_roots_t roots;
double d;
d = b*b - 4*a*c;
if (d < 0.0) {
roots.num_roots = 0;
} else if (d == 0.0) {
roots.num_roots = 1;
roots.roots[0] = -b / (2 * a);
} else {
roots.num_roots = 2;
roots.roots[0] = (-b - sqrt(d)) / (2 * a);
roots.roots[1] = (-b + sqrt(d)) / (2 * a);
}
return roots;
}
I'd say it's not great to do. What you could do is something like this:
int quadratic_equation(double a, double b, double c, double *root_a, double *root_b) {
double discriminant = ((b*b) - (4*a*c));
if (discriminant < 0) {
return -1;
}
if (root_a != NULL) {
*root_a = (-b + sqrt(discriminant)) / (2 * a);
}
if (root_b != NULL) {
*root_b = (-b - sqrt(discriminant)) / (2 * a);
}
return 0;
}
Then you could call that like so:
double root_a;
double root_b;
int ok = quadratic_equation(a, b, c, &root_a, &root_b);
if (ok < 0) {
// It wasn't OK. Print out an error.
} else {
// It was OK. Print out the results.
}
Note that you should also check other error cases in the function and return -1 for them as well. E.g. a being zero.
Consider using the return value to indicate whether everything worked, and passing an array to the function to receive the return values:
enum QE_Status { QE_OK = 0, QE_NON_QUADRATIC, QE_COMPLEX_ROOTS, QE_NULL_POINTER };
enum QE_Status quadratic_equation(double a, double b, double c, double *r)
{
double discriminant;
if (r == 0)
return QE_NULL_POINTER;
if (a == 0.0)
return QE_NON_QUADRATIC;
discriminant = (b * b) - (4 * a * c);
if (discriminant < 0)
return QE_COMPLEX_ROOTS;
discriminant = sqrt(discriminant);
r[0] = (-b + discriminant) / (2 * a);
r[1] = (-b - discriminant) / (2 * a);
return QE_OK;
}
You can extend the system to handle numerical instability (because b*b is almost equal to 4*a*c, or because a is very small, etc).
The calling code can then be:
double a, b, c, x[2];
if (quadratic_equation(a, b, c, x))
...oops, something went wrong...
Or:
switch (quadratic_equation(a, b, c, x))
{
case QE_OK:
...print or use results in x...
break;
case QE_NON_QUADRATIC:
case QE_COMPLEX_ROOTS:
...print appropriate error message about user's data...
break;
case QE_NULL_POINTER:
...Oops - programming error...
break;
}
I would certainly call it bad practice because the code is very unclear.
Firstly, you are calling the function three times, when once should be enough.
I'd consider returning/filling a list in your quadratic_equation() function instead of returning the roots one by one.
This would also allow you to determine if there are real roots -- if there aren't, just return an empty list.
As a whole, this would be much more elegant than your current solution, and it would eliminate the need for checking whether there are any solutions beforehand.