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.
Related
I want to pass different amount of arguments by satisfying condition to the function. But the problem is the arguments have to be the same amount of parameter of a function.In every condtion I have different variables value which I want to pass as arguments. How can avoid this and successfully execute my code.
#include<stdio.h>
float file_w(float root1,float root2, float real,float imag)
{
FILE *fileWrite;
fileWrite= fopen("fileNames.txt", "a+");
if(root2==NULL && real==NULL && imag==NULL){
fprintf(fileWrite,"%.2f",root1);
fclose(fileWrite);
}
}
float file_r()
{
system("cls");
printf("\n\n\n\t\t\t\tCalculation History\n\n\t\t\t\t");
FILE *file;
char c;
file=fopen("fileName.txt","r");
if(file==NULL)
{
printf("file not found");
}
else
{
while(!feof(file))
{
c=fgetc(file);
printf("%c",c);
}
fclose(file);
printf("\n");
system("Pause");
main();
}
}
int main(){
double a, b, c, discriminant, root1, root2, realPart, imagPart;
int opt;
printf("Enter coefficients a, b and c: \n");
scanf("%lf", &a);
scanf("%lf",&b);
scanf("%lf",&c);
discriminant = b * b - 4 * a * c;
if (discriminant > 0)
{
root1 = (-b + sqrt(discriminant)) / (2 * a);
root2 = (-b - sqrt(discriminant)) / (2 * a);
printf("\n\t\t\t\troot1 = %.2lf and root2 = %.2lf\n\n\t\t\t\t", root1, root2);
file_w(root1,root2);
}
else if (discriminant == 0)
{
root1 = root2 = -b / (2 * a);
printf("\n\t\t\t\troot1 = root2 = %.2lf\n\n\t\t\t\t", root1);
file_w(root1);
}
else
{
realPart = -b / (2 * a);
imagPart = sqrt(-discriminant) / (2 * a);
printf("\n\t\t\t\troot1 = %.2lf + %.2lfi and root2 = %.2f - %.2fi\n\n\t\t\t\t", realPart, imagPart, realPart, imagPart);
file_w(realPart,imagPart);
}
return 0;
}
Variable Length Argument in C
Variable length argument is a feature that allows a function to receive any number of arguments. There are situations where we want a function to handle variable number of arguments according to requirement.
Sum of given numbers.
Minimum of given numbers.
and many more.
Variable number of arguments are represented by three dotes (…)
For example:
#include <stdio.h>
#include <stdarg.h>
double average(int num,...) {
va_list valist;
double sum = 0.0;
int i;
/* initialize valist for num number of arguments */
va_start(valist, num);
/* access all the arguments assigned to valist */
for (i = 0; i < num; i++) {
sum += va_arg(valist, int);
}
/* clean memory reserved for valist */
va_end(valist);
return sum/num;
}
int main() {
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}
I have to use prototype poly float to compute f(x)=5x^2+12.55x+0.75. I have error every time I run this code because poly is not used. Any help will be good and any tips for prototypes too.
#include<stdio.h>
float poly(float x)
{
return 1;
}
int main()
{
float b, c, a;
printf("Podaj x=");
a = scanf("%f", &b);
c = 5 * b * b + 12.55 * b + 0.75;
if(a<1)
{
printf("Incorrect input");
return 1;
}else
{
printf("Wynik: %.2f", c);
return 0;
}
}
Change poly to:
float poly(float x)
{
return 5*x*x + 12.55*x + .75;
}
In main, you can use the function:
print("poly(%g) = %g.\n", b, poly(b));
I have to write a code for the c language for class but I'm getting this errors because the code is not returning the value correctly for some reason that I don't understand at all.
Requirements:
Tickets for the amusement park for the day cost $30.00 per adult, and $12.00 per child. There is also a 10% discount if more than 10 tickets are ordered in total.
Given two integer variables, num_adults, and num_children, calculate the total cost for amusement park admission for the day and store it in double variable total_cost.
my code: (you can assume every variable has been properly initialized. )
if (num_adults + num_children > 10)
{
total_cost =((30.00 * num_adults) + (12.00 * num_children)) - (0.10 * ((30.00 * num_adults) + (12.00 * num_children)));
printf("%d\n", total_cost);
}
else
{
total_cost=((30.00 * num_adults) + (12.00 * num_children));
printf("%d\n", total_cost);
}
Here's my best guess: You want to output it not as an integer (%d) but as a float %f
so do this:
printf("%.2f\n", total_cost);
#include <stdio.h>
int total_tickets(int c, int a)
{
return (c + a);
}
float total_cost(int c, int a)
{
return ((12.00 * c) + (30.00 * a));
}
float discounted_cost(int c, int a)
{
return (total_cost(c, a) * 0.9);
}
float actual_cost(int c, int a)
{
if(total_tickets(c, a) < 10)
{
return (total_cost(c, a));
}
else
{
return (discounted_cost(c, a));
}
}
int main(void) {
int c, a;
c = 2; a = 2;
printf("%.2f\n", actual_cost(c, a));
c = 5; a = 5;
printf("%.2f\n", actual_cost(c, a));
return 0;
}
I'm having a difficult time figuring out how'd I'd accomplish a task and am looking for help.
So, I need to use a function that'll find a pair of numbers (to be allocated dynamically) that meets a condition and returns a pointer to it.
Here's what I have:
int* f_cubes_sum(int n)
{
//Declaring array
int *numSet;
numSet = (int *)malloc(2); // Only two because I'm looking for a pair
//Declaring variables
int sum = 0;
int a = 0;
int b = 0;
bool results = false;
while (b < n && results == false)
{
while (a < n)
{
sum = a^3 + b^3;
if (sum == n)
{
results = true;
}
else
{
a = a + 1;
}
sum = 0;
}
if (results = false)
{
a = 0;
b = b + 1;
}
}
if (results = false)
{
a = NULL;
b = NULL;
}
numSet[0] = a;
numSet[1] = b;
free(numSet);
return numSet;
}
And in my main function, how would I access both numbers?
Thank you for your time
You are looking for a function that determines whether a number can be written a the sum of two cubes and if so, it should yield the two numbers whose cubes are summed. Basically you need:
an information on whether n can be written as a³ + b³ and
if so, the values of a and b.
You can use your approach of allocating an array of two integers and return that on success and NULL on failure. If you do so, you should allocate the array only if you have a result:
int *f_cubes_sum(int n)
{
int a, b;
// logic to work out whether a³ + b³ == n
if (a*a*a + b*b*b == sum) {
int *res = malloc(2 * sizeof(*res));
res[0] = a;
res[1] = b;
return res;
}
// no solution found
return NULL;
}
The drawback here is that the calling code has to free the returned pointer:
int *res = f_cubes_sum(2778);
if (res) {
printf("%d, %d\n", res[0], res[1]);
free(res);
}
Another approach is to pass in an array that your code has to fill and indicate success or failure with a boolean return value:
bool f_cubes_sum(int n, int res[2])
{
int a, b;
// logic to work out whether a³ + b³ == n
if (a*a*a + b*b*b == sum) {
res[0] = a;
res[1] = b;
return true;
}
// no solution found
return false;
}
Now the calling code has to provide the space for the result:
int res[2];
if (f_cubes_sum(2778, res)) {
printf("%d, %d\n", res[0], res[1]);
}
Of course, because you are always dealing with two possible result values, you could also pass pointers to these values instead of passing an array. Here's a variant of your function that does this:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool f_cubes_sum(int n, int *pa, int *pb)
{
int a = 0;
while (1)
{
int a3 = a*a*a;
if (a3 > n) break;
int b = cbrt(n - a3) + 0.5;
int b3 = b*b*b;
if (a3 + b3 == n) {
*pa = a;
*pb = b;
return true;
}
a++;
}
return false;
}
int main(void)
{
int a, b;
int n = 35001;
if (f_cubes_sum(n, &a, &b)) {
printf("%d^3 + %d^3 == %d\n", a, b, n);
} else {
printf("Nothing found for %d.\n", n);
}
return 0;
}
Also note what commenters have alreadey pointed out:
In C, = assigns, == compares. Unfortunately, an assignment inside an iF condition is valid C: It will assign the value and then test it, entering the clause if it isn't 0 or false. Therefore if (x = false) never enters the if clause. Switch on warnings to carch such mistakes.
The ^ operator isn't the power operator, it is the bitwise xor operator. Raising a number a to the power of b is done with the floating-point function pow(a, b). If the exponent is a known small integer, it is usually better to write the multiplication explicitly. Thus, pow(a, 3) is rendered better as a*a*a.
When allocating memory, be sure the make enough room for the desired type. Also don't use freed pointers; the memory they point to is invalid.
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