I can't work out why my program isn't doing what it's supposed to do. The task was to make a c program that can solve quadratic using two c files. This is the code called interface.c that we got to work with, nothing has to be changed on this one:
#include <stdio.h>
void abc (void);
int a, b, c;
extern double x1real, x1imag, x2real, x2imag;
static void get_parameters (void)
{
scanf("%d", &a);
scanf("%d", &b);
scanf("%d", &c);
}
void print_solution(void)
{
printf("The roots of %dx^2 + %dx + %d are:\n",a,b,c);
if(x1imag == 0 && x2imag == 0)
{
if(x1real == x2real)
{
printf("x = %.4f\n", x1real);
}
else
{
printf("x1 = %.4f, x2 = %.4f\n", x1real, x2real);
}
}
else
{
printf("x1 = %.4f+%.4fi, x2 = %.4f-%.4fi\n", x1real, x1imag, x2real, x2imag);
}
}
int main (void)
{
int runs, run;
scanf("%d",&runs);
for(run=0; run < runs; run++)
{
get_parameters();
abc();
print_solution();
}
return 0;
}
Next is the code I made which isn't working, there seems to go something wrong with the integer types I think. With every quadratic formula it will output x1 = nan x2 = nan. There is something wrong with the integer type but can't figure out which.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
extern int a, b, c;
double x1real, x1imag, x2real, x2imag;
int discriminant(void)
{
int discriminant;
discriminant = (pow(b,2)-4*a*c);
return discriminant;
}
void abc (void)
{
if (discriminant() > 0)
{
x1real = (-b - sqrt(discriminant()))/(2*a);
x2real = (-b + sqrt(discriminant()))/(2*a);
x1imag = 0;
x2imag = 0;
}
else
{
x1real = x2real = (-b) / (2*a);
x1imag = (-b - sqrt(-discriminant())) / (2*a);
x2imag = (-b + sqrt(-discriminant())) / (2*a);
}
return;
}
input:
4
2 0 0
1 3 2
3 4 9
1 0 1
output:
The roots of 2x^2 + 0x + 0 are:
x = 0.0000
The roots of 1x^2 + 3x + 2 are:
x1 = -1.0000, x2 = -2.0000
The roots of 3x^2 + 4x + 9 are:
x1 = -0.6667+-2.2653i, x2 = -0.6667-0.9319i
The roots of 1x^2 + 0x + 1 are:
x1 = 0.0000+-1.0000i, x2 = 0.0000-1.0000i
suspected output:
The roots of 2x^2 + 0x + 0 are:
x = 0.0000
The roots of 1x^2 + 3x + 2 are:
x1 = -1.0000, x2 = -2.0000
The roots of 3x^2 + 4x + 9 are:
x1 = -0.6667+1.5986i, x2 = -0.6667-1.5986i
The roots of 1x^2 + 0x + 1 are:
x1 = 0.0000+1.0000i, x2 = 0.0000-1.0000i
Quadratic formula?
conditional expression of「b^2-4ac≧0」 is not called, is it?
int discriminant(void)
{
int discriminant;
discriminant = (pow(b,2)-4*a*c);
return discriminant;
}
void abc (void)
{
// if (discriminant > 0) // it doesn't call [int discriminant(void)]
if (discriminant() >= 0)
{
x1real = (-b - sqrt(discriminant()))/(2*a);
x2real = (-b + sqrt(discriminant()))/(2*a);
x1imag = 0;
x2imag = 0;
}
else
{
x1real = x2real = (-b) / (2*a);
x1imag = (-b - sqrt(-discriminant())) / (2*a);
x2imag = (-b + sqrt(-discriminant())) / (2*a);
}
return;
}
(An addition)
static void get_parameters (void)
{
do {
scanf("%d", &a);
scanf("%d", &b);
scanf("%d", &c);
} while(a == 0)
}
Related
I'm programing on Code Composer Studio a program that generate and show a sinusoid, this program should normally be implemented in a DSP, but since I don't have the DSK I'm just compiling it and trying to show the result in CCS.
I'm having a problem in the line 18 it shows that an expression is expected and I don't know why. I checked all comas and () {} and it seems correct.
#include <math.h>
#include <stdio.h>
const int sine_table[40] = { 0, 5125, 10125, 14876, 19260, 23170, 26509, 29196, 31163, 32364, 32767, 32364, 31163, 29196, 26509, 23170, 19260, 14876, 10125, 5125, 0, -5126, -10126, -14877, -19261, -23171, -26510, -29197, -31164, -32365, -32768, -32365, -31164, -29197, -26510, -23171, -19261, -14877, -10126, -5126 };
int i = 0;
int x1 = 0;
int x2 = 0;
float y = 0;
float sin1(float phase) {
x1 = (int) phase % 40; if (x1 < 0) x1 += 40; x2 = (x1 + 1) % 40;
y = (sine_table[x2] - sine_table[x1]) * ((float) ((int) (40 * 0.001 * i * 100) % 4100) / 100 - x1) + sine_table[x1];
return y;
}
int main(void) {
double pi = 3.1415926535897932384626433832795;
for (int i = 0; i < 1000; i++) {
float x = 40 * 0.001 * i;
float radians = x * 2 * pi / 40;
printf("%f %f %f\n", x, sin1(x) / 32768, sin(radians));
i = i + 1;
}
}
I need to print the imaginary root in the quadratic equation.
but when I execute my code the result shows me that the imaginary root is 0.00000i.
even I use to <complex.h> also same.
Can everybody help me to check the code that I bold?
//C program to find the root of the quadratic equation
#include<stdio.h>
#include<math.h>
#include<complex.h>
int main()
{
double a, b, c, x, x1, x2, disc, xr, ximg1, ximg2;
printf("Please enter the value of quadratic equation, a: ");
scanf("%lf", &a);
printf("Please enter the value of quadratic equation, b: ");
scanf("%lf", &b);
printf("Please enter the value of quadratic equation, c: ");
scanf("%lf", &c);
if( a == 0 )
{
x = -(c/b);
printf("\nThis is not a quadratic equation.\n");
printf("x = %.3lf", x);
}
else{
disc = (b*b) - 4*a*c;
if( disc == 0 ){
x1 = -b / 2 * a;
x2 = -b / 2 * a;
printf("x1 = %lf, x2 = %lf", x1, x2);
}
else if(disc > 0){
x1 = ( -b + sqrt( disc ) ) / 2 * a;
x2 = ( -b - sqrt( disc ) ) / 2 * a;
printf("x1 = %.1lf, x2 = %.1lf", x1, x2);
}
else{
ximg1 = sqrt( disc ) / 2 * a;
ximg2 = - sqrt( disc ) / 2 * a;
xr = - b / ( 2 * a );
**printf("xr = %lf, ximg1 = %lfi, ximg2 = %lfi", crealf(xr), cimagf(ximg1), cimagf(ximg2));**
}
}
return 0;
}
The output are shown as below:
Please enter the value of quadratic equation, a: 4
Please enter the value of quadratic equation, b: 1
Please enter the value of quadratic equation, c: 3
xr = -0.125000, ximg1 = 0.000000i, ximg2 = 0.000000i
Process returned 0 (0x0) execution time : 3.914 s
Press any key to continue.
You should print the roots as complex numbers using the computed real and imaginary parts. No need for <complex.h> nor complex types:
double xr = - b / ( 2 * a );
double ximg1 = -sqrt( -disc ) / (2 * a);
double ximg2 = -ximg1;
printf("x1 = %lf%+lfi, x2 = %lf%+lfi\n", xr, ximg1, xr, ximg2);
As you have used complex header file you just need to use the csqrt() instead of sqrt(),
//C program to find the root of the quadratic equation
#include<stdio.h>
#include<math.h>
#include<complex.h>
int main()
{
double a, b, c, x, x1, x2, disc, xr, ximg1, ximg2;
printf("Please enter the value of quadratic equation, a: ");
scanf("%lf", &a);
printf("Please enter the value of quadratic equation, b: ");
scanf("%lf", &b);
printf("Please enter the value of quadratic equation, c: ");
scanf("%lf", &c);
if( a == 0 )
{
x = -(c/b);
printf("\nThis is not a quadratic equation.\n");
printf("x = %.3lf", x);
}
else{
disc = (b*b) - 4*a*c;
if( disc == 0 ){
x1 = -b / 2 * a;
x2 = -b / 2 * a;
printf("x1 = %lf, x2 = %lf", x1, x2);
}
else if(disc > 0){
x1 = ( -b + csqrt( disc ) ) / 2 * a;//changed the function here
x2 = ( -b - csqrt( disc ) ) / 2 * a;//changed the function here
printf("x1 = %.1lf, x2 = %.1lf", x1, x2);
}
else{
ximg1 = sqrt( disc ) / 2 * a;
ximg2 = - sqrt( disc ) / 2 * a;
xr = - b / ( 2 * a );
**printf("xr = %lf, ximg1 = %lfi, ximg2 = %lfi", crealf(xr), cimagf(ximg1), cimagf(ximg2));**
}
}
return 0;
}
Complex types not needed
When code reaches the below, disc < 0. Find the square root of the negation.
// ximg1 = sqrt( disc ) / 2 * a;
ximg1 = sqrt( -disc ) / 2 * a; // Use -disc
// ximg2 = - sqrt( disc ) / 2 * a;
ximg2 = -ximg1; // Simply negate ximg1
xr = - b / ( 2 * a );
printf("xr = %lf, ximg1 = %lfi, ximg2 = %lfi",
// crealf(xr), cimagf(ximg1), cimagf(ximg2));
xr, ximg1, ximg2);
Tip: use "%e", it is more informative.
printf("xr = %le, ximg1 = %lei, ximg2 = %lei",
xr, ximg1, ximg2);
Bug
Instead of / 2 * a;, in various places, certainly you want / (2 * a);.
I was given a problem to write a C program which would solve the equation ax2+bx+c=0, where a, b and c are coefficients with double type. Any of the coefficients may be zero. In this problem it is unclear to me how to handle the double variables.
Here is my code. As for now, I know that my program can't distinguish between two roots and infinitely many roots. It also doesn't detect the "linear equation situation". How can I make it detect an infinite number of solutions? I was also advised in the comments to calculate the root with the minus before the discriminant if b > 0 and then use the Viet's theorem. I understand that it is because it is always more accurate to sum two numbers. I also guess I should do the exact opposite with b < 0. But what if b == 0 ? In this case, the program will not do anything. Or should I just include b == 0 in b < 0 and have b <= 0 ?
#include <stdio.h>
#include <math.h>
#include <float.h>
int main() {
double a, b, c, x1, x2;
scanf("%lf", &a);
scanf("%lf", &b);
scanf("%lf", &c); // just reading variables
//ax^2+bx+c=0
if ((b * b - 4 * a * c) < 0) {
printf("no");
} else {
x1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a); //calculating roots
x2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
if ((fabs((a * x1 * x1 + b * x1 + c)) < DBL_EPSILON) & (fabs((a * x2 * x2 + b * x2 + c)) < DBL_EPSILON)) { //plugging the roots in
if (fabs((x1 - x2)) < DBL_EPSILON) { //checking if the roots are equal
printf("%lf", &x1); // if they are equal, we print only one of them
} else {
printf("%lf", &x1); // if they are not equal, we print both.
printf("\n %lf", &x2);
}
} else { // if there are no two valid roots
if ((fabs((a * x1 * x1 + b * x1 + c)) < DBL_EPSILON)) // we try to find one root.
printf("%lf", &x1);
if (fabs((a * x2 * x2 + b * x2 + c)) < DBL_EPSILON)
printf("%lf", &x2);
if ((fabs((a * x1 * x1 + b * x1 + c)) > DBL_EPSILON) & (fabs((a * x2 * x2 + b * x2 + c)) > DBL_EPSILON)) // if both of the plugged roots don't satisfy the equation
printf("no");
}
}
return 0;
}
Solve quadratic equation when coefficients may be 0
How can I make it detect an infinite number of solutions?
When a==0 && b == 0 && c == 0.
No DBL_EPSILON needed really anywhere in this code. See also #Eric Postpischil.
But what if b == 0 ?
if (b == 0) { // y = a*x*x + c
if (a) {
double dd = -c/a;
if (dd >= 0) {
double d = sqrt(d);
printf_roots("+/- roots", d,-d);
} else {
printf_roots("Complex roots", NAN, NAN); // Note NAN may not exist
}
} else if (c) { // y = 0*x*x + c, c != 0
printf_roots("No roots", NAN, NAN);
} else { // y = 0*x + 0
printf_roots("Infinite roots", -HUGE_VAL, HUGE_VAL);
}
Or should I just include b == 0 in b < 0 and have b <= 0 ?
Unless the coding goal requires a special output when b==0, I would only vector code on b==0 as a subtest when a==0 occurred.
if (a==0) {
if (b == 0) {
The quadric equation, like much FP code, can readily overflow and hit 0, both cases losing all precision.
Consider the code below: the unnecessary subtraction may cause overflow or truncation to 0 versus the second which may not. It is dependent on many things.
if ((b * b - 4 * a * c) < 0)
//
if (b * b < 4 * a * c)
Further, C allows various calculations to occur using wider math. Research FLT_EVAL_METHOD. Because of this, to prevent sqrt(value_less_than_0), code should calculate the discriminate and then test the object x that is going to be applied to sqrt(x).
//if ((b * b - 4 * a * c) < 0) {
// printf("no");
//} else {
// x1 = (-b + sqrt(b * b - 4 * a * c))
double discriminate = b * b - 4 * a * c;
if (discriminate < 0) {
printf("no");
} else {
double d = sqrt(discriminate);
x1 = (-b + d)
As to the idea of "calculate the root with the minus before the discriminant if b > 0 and then use the Viet's theorem", I'd suggest for improved retained precision the below which does not subtract like signed values.
double d = sqrt(discriminate);
// Note x1*x2 = c/a
if (b < 0) {
x2 = (-b + d)/(2*a);
x1 = c/a/x2;
} else {
x1 = (-b - d)/(2*a);
x2 = c/a/x1;
}
printf_roots("2 roots", x1, x2);
Notes on printf("%lf", &x1);. You are not compiling with all warnings enabled. Save time - enable them. Should be printf("%lf", x1); No &.
Further double is floating point. For FP code development use "%e", "%a" or"%g" to full see significant information.
printf("%g\n", some_double);
// or better
printf("%.*e\n", DBL_DECIMAL_DIG -1, some_double);
Since division by zero is not allowed, you have to split the problem into 4 cases :
a != 0:
this is case you treated in your code.
a == 0 && b != 0 :
This is a linear equation where the solution is x = -c/b
a == 0 && b == 0 && c != 0 : There's no possible value for x.
In this last case, a, b and c are equals to 0 : there's infinitly many solutions for x.
EDIT: comparisons with epsilon removed since they seem to be useless
There are some problems in your code:
you should check the return values of scanf() to avoid undefined behavior on invalid input.
you should use local variables for intermediary results to improve code readability
your printf statements are incorrect: you should pass the values of the double variables instead of their addresses: printf("%lf", &x1); should read:
printf("%f", x1);
Regarding the degenerate cases, you should just test those before trying to resolve the second degree equation.
Here is a corrected version:
#include <stdio.h>
#include <math.h>
int main() {
double a, b, c, delta, x1, x2;
if (scanf("%lf%lf%lf", &a, &b, &c) != 3) {
printf("invalid input\n");
return 1;
}
if (a == 0) {
// not a quadratic equation
if (b != 0) {
printf("one solution: %g\n", -c / b);
} else {
if (c != 0) {
printf("no solution\n");
} else {
printf("all real values are solutions\n");
}
}
} else {
delta = b * b - 4 * a * c;
if (delta < 0) {
printf("no real solution\n");
} else
if (delta == 0) {
printf("one double solution: %g\n", -b / (2 * a));
} else {
x1 = (-b + sqrt(delta)) / (2 * a);
x2 = (-b - sqrt(delta)) / (2 * a);
printf("two solutions: %g, %g\n", x1, x2);
}
}
return 0;
}
Whenever I try running this, it returns the wrong solution, for example:
A: 303
B: 405
C: 50
Real solution: −0.13762776465722773
My solution : -110079.531250
#include <stdio.h>
#include <math.h>
int main(){
float a;
float b;
float c;
float solution;
float d;
printf("A: ");
scanf("%f", &a);
printf("B: ");
scanf("%f", &b);
printf("C: ");
scanf("%f",&c);
d = b * b - 4 * a * c;
solution = (-b - sqrt(d))/ 2*a;
printf("%f", solution);
}
You forgot BODMAS. Replace (-b - sqrt(d))/ 2*a by (-b - sqrt(d))/ (2*a)
solution = (-b - sqrt(d))/ (2*a);
Two things.
You need to watch out for the order of operations.
solution = (-b - sqrt(d)) / (2*a);
And depending on your customer you need to consider the accuracy of your result.
See "Avoiding loss of significance" for more information
And finally - i had a bit of fun writing my own version of your program:
#include <stdio.h>
#include <math.h>
void printLineSolution( double a, double b, double c );
int main()
{
printLineSolution(303,405,50);
printLineSolution(1,2,0);
printLineSolution(1,2,-1);
printLineSolution(1,-2,-3);
printLineSolution(1,-6,9);
printLineSolution(1,3,3);
getchar();
}
void printLineSolution( double a, double b, double c )
{
double d = (b * b) - (4 * a * c);
printf("(%lg)x^2 + (%lg)x + (%lg) = 0 ", a, b, c);
if( a == 0 )
{
printf("=> not quadratic");
}
else
{
if( 0 > d )
{
double r = - b / (2*a);
double i = sqrt( -d ) / (2*a);
printf("=> 2 complex: %lg + %lgi ; %lg - %lgi", r, i, r, i);
}
else if ( 0 == d )
{
double solution = - b / (2*a);
printf("=> 1 real: %lg", solution);
}
else
{
double s1 = (- b + sqrt( d ) ) / (2*a);
double s2 = (- b - sqrt( d ) ) / (2*a);
printf("=> 2 real: %lg ; %lg", s1, s2);
}
}
printf("\n");
}
I am trying to write a program to perform point operations on a elliptic curve in a prime field I am using the standard formulaes for point additions and doubling in my code and these operations are performed by functions that are called but I am getting output for certain points but not all so please help me to fix the problem that are present in this code.
structure point_multiply(int x, int y, int k )
{
int xk;
int yk,m;
xk=x;
yk=y;
m=1;
int xL,yL,s,e;
e=findInverse((2*yk),211);
if((((3*(xk*xk))*e)% 211)>0)
{s = (((3*(xk*xk))*e)% 211);
}
else
s=(((3*(xk*xk))*e)% 211)+ 211;
if((((s*s)- (2*xk)) % 211)>0)
{xL=(((s*s)- (2*xk)) % 211);
}
else
xL=(((s*s)- (2*xk)) % 211) + 211;
if(((-yk+ s*(xk-xL)) % 211) > 0)
yL=(-yk+ s*(xk-xL)) % 211;
else
yL=(-yk+ s*(xk-xL)) % 211 + 211;
xk=xL;
yk=yL;
m=m+1;
while(k>m)
{
sn=point_addition(xk,yk,x,y);
xk=sn.a;
yk=sn.b;
m++;
}
s1.a=xk;
s1.b=yk;
return s1;
}
structure point_addition(int x1, int y1, int x2, int y2)
{
int s,xL,yL;
if((x1-x2)!=0)
{
if ( x1 == 0 && y1 == 0 )
{
xL = x2;
yL = y2;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( x2 == 0 && y2 == 0 )
{
xL = x1;
yL = y1;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( y1 == -y2 )
{
xL = yL = 0;
s7.a=xL;
s7.b=yL;
return s7;
}
l=findInverse((x1-x2),211);
if ((((y1-y2)*l) % 211)>=0)
s=((((y1-y2)*l) % 211));
else
s=(((y1-y2)*l) % 211) + 211;
if ((((s*s)-(x1+x2)) % 211)>0)
xL= (((s*s)-(x1+x2)) % 211) ;
else
xL= (((s*s)-(x1+x2)) % 211) + 211;
if(((-y1+s*(x1-xL)))>=0)
yL= ((-y1+s*(x1-xL)) % 211);
else
yL= ((-y1+s*(x1-xL)) % 211) + 211;
}
else
{
xL= 0 ;
yL= 0;
}
s7.a= xL;
s7.b= yL;
return s7 ;
}
int findInverse(int a, int b)
{
int x[3];
int y[3];
int quotient = a / b;
int remainder = a % b;
x[0] = 0;
y[0] = 1;
x[1] = 1;
y[1] = quotient * -1;
int i = 2;
for (; (b % (a%b)) != 0; i++)
{
a = b;
b = remainder;
quotient = a / b;
remainder = a % b;
x[i % 3] = (quotient * -1 * x[(i - 1) % 3]) + x[(i - 2) % 3];
y[i % 3] = (quotient * -1 * y[(i - 1) % 3]) + y[(i - 2) % 3];
}
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
if(x[(i - 1) % 3]<0)
return x[(i - 1) % 3]+211;
else
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
return x[(i - 1) % 3];
}
Edited and added main c code which uses these function to perform elliptic curve cryptography
int main()
{
int y,z=0,x=2,i[200],j[200],h=0,g,k;
while(x<200)
{
y=sqrt((x*x*x)-4);
z=modulo(y,211);
if(z!=0)
{
i[h]=x;
j[h]=z;
s[h].a=i[h];
s[h].b=j[h];
s[h+1].a=i[h];
s[h+1].b=(211 - j[h]);
printf("\nh=%d X= %d Y= %d \nh=%d X= %d Y= %d",h,s[h].a,s[h].b,h+1,s[h+1].a,s[h+1].b);
h=h+2;
}
x++;
}
printf("The total no of points we have on our elliptic curve for cryptography is %d",h-1);
x=5;
y=11;
printf("\n %d %d\n",x,y );
printf("\nEnter A number between 0 and the private key");
scanf("%d",&k);
s2=point_multiply(x,y,k);
printf("\n The public key is \n %d %d \n ",s2.a,s2.b );
printf("Enter a RANDOM number to generate the cipher texts");
scanf("\n%d",&g);
s3= point_multiply(x,y,g);
s4=point_multiply(s2.a,s2.b,g );
label:
printf("\n Enter a number to send");
scanf("%d",&h);
s6=point_addition(s4.a,s4.b,s[h].a,s[h].b);
printf("The points to be sent are X= %d Y=%d",s[h].a,s[h].b);
printf(" \n X= %d Y=%d\n X = %d Y= %d ",s3.a,s3.b,s6.a,s6.b);
//RECIEVER
s8=point_multiply(s3.a,s3.b,k);
s9=point_addition((s8.a) ,-((s8.b)%211),s6.a,s6.b);
printf(" The decrypted points are \n %d %d",s9.a,s9.b);
printf("\n If you have more no to send press 1 else press 0");
scanf("\n %d", &x1);
if(x1==1)
goto label;
else
return 0;
}
s1, s2, s3 etc are structures which hold a 2 integers which act as x and y co-ordinates
I am getting output by entering k=3,g=4, h=5 and many other cases mostly with small numbers but not for larger numbers. What could be wrong with the code?
Further edit: I guess that normal square root method is not applicable to find square roots of a modular no?.. Please tell me how to find the modular square root of a no?