Validating a triangle in C - c

I'm new in C, so I try to create a program that calculate the area of triangle as a start.
Calculating the area is easy when the triangle exists, however the validation of straight line is working partially.
Example:
A(0,-4) B(1,0) C(4,12) does not produce straight line error.
but
A(4,12) B(1,0) C(0,-4) produce straight line error.
#include <stdio.h>
#include <math.h>
double square(double num){
return (num*num);
}
int main()
{
double x[5],y[5],a,b,c,angle,area;
printf("Hello there! Calculating the area of triangle.\n");
printf("Enter a coordinate A :\n");
scanf("%lf,%lf",&x[0],&y[0]);
printf("Enter another coordinate B :\n");
scanf("%lf,%lf",&x[1],&y[1]);
printf("Enter another coordinate C :\n");
scanf("%lf,%lf",&x[2],&y[2]);
// AB as base (a) , c is opposite side
a = sqrt( square((x[0]-x[1])) + square((y[0]-y[1])) );
b = sqrt( square((x[0]-x[2])) + square((y[0]-y[2])) );
c = sqrt( square(x[1]-x[2]) + square((y[1]-y[2])) );
double num = (square(a)+square(b)-square(c))/(2*a*b);
angle = acos(num);
area = .5*a*b*sin(angle);
//printf("%lf %lf %lf %lf %lf \n",a,b,c,num,angle);
if (num == 1 || num ==-1){
printf("That's a straight line.");
}else{
printf("Area of triangle is %lf\n",area);
}
return 0;
}

You can use a different test, and perhaps a different area formula. If you use Heron's formula, then once you have the lengths of the sides a, b, and c, you can compute:
double p = (a + b + c)/2;
double area = sqrt(p*(p-a)*(p-b)*(p-c));
You can detect if the triangle is valid by checking that p is greater than each of the sides.
double p = (a + b + c)/2;
if ((p > a) && (p > b) && (p > c)) {
double area = sqrt(p*(p-a)*(p-b)*(p-c));
printf("Area of triangle is %lf\n", area);
} else {
printf("I don't consider that a triangle.\n");
}
Try it online!

The problem in your code is double num = (square(a)+square(b)-square(c))/(2*a*b); gets evaluated to a number slightly larger than 1 in some cases. This can happen with floating point computations. In your case you can safely add if (num > 1) num = 1; after that line since cosine equation always will give you a value larger than 0 and less than 1 for triangles.
However there's a problem if two points overlap and a or b becomes zero. You will have to check for that and handle it as a special case if such input is expected by your code. (If two points overlap then they are collinear anyways. You can check the overlap by checking if any of a,b,c are zero)

Related

Roots of equation in C

I am relatively new to C, and am trying to improve myself in it. I made a calculator and added the quadratic equation solver to it, cause i know the formula of finding the roots. But i am faced with two problems.
Code:
#include <stdio.h>
#include <maths.h>
#include <stdlib.h>
#include <windows.h>
main(){
float A1, A2, A, B, C, ans, Z;
printf("Welcome to Quadratic Equation solver. Enter the coefficient of X^2, followed by\nthe coefficient of X, followed by the integer value.\n\nEnter values: ");
scanf("%f%f%f", &A, &B, &C);
CheckF = (B * B - 4 * A * C);
if (CheckF < 0) {
system("COLOR B4");
printf("This calculator HeX, currently cannot handle complex numbers.\nPlease pardon my developer. I will now redirect you to the main menu.\n");
system("pause");
system("cls");
system("COLOR F1");
goto Start;
} else if (CheckF >= 0) {
Z = pow(CheckF, 1/2);
A1 = (-B + Z)/(A+A);
A2 = (-B - Z)/(A+A);
if (A1 == A2) {
ans = A1;
printf("\nRoot of equation is %f (Repeated root)\n", ans);
Sleep(250);
} else if (A1 != A2) {
printf("Roots of equation are %f and %f \n", A1, A2);
Sleep(250);
}
}
}
Problem 1:
When i run the code and input 3 32 2, mathematically the output should be Roots of equation are -0.06287 and -10.6038, that i double checked with my sharp calculator. However, the output that i got was was off: Roots of equation are -5.166667 and -5.500000 i am totally unsure why is it not computing the correct roots of the equation.
Problem 2:
Some roots do not have the coefficient of X^2, for example (2X + 2), which can be solved to get repeated roots of -2, (6X - 3), which gives us that x is 0.5 repeated. However, according to the quadratic equation, which is divided by 2A, will never work, as it is divided by 0. What is the possible way out of this situation? Is it to check if A = 0 then do something else? Any help will be appreciable.
integer division
pow(CheckF, 1/2) is 1.0 as 1/2 is integer division with a quotient of 0.
// Z = pow(CheckF, 1/2);
Z = pow(CheckF, 1.0/2.0);
// or better
Z = sqrt(CheckF);
// Even better when working with `float`.
// Use `float sqrtf(float)` instead of `double sqrt(double)`.
Z = sqrtf(CheckF);
Best - re-write using double instead of float. Scant reason for using float here. double is the C goto floating point type.
Other issue
//#include <maths.h>
#include <math.h>
// main() {
int main(void) {
// CheckF = (B * B - 4 * A * C);
float CheckF = (B * B - 4 * A * C);
// goto Start;
Use an auto formater
I see some problems with the code. First, I suggest you to use double instead of float. They offer much better precision and an ideal calculator needs precision. Secondly, you do:
Z = pow(CheckF, 1/2);
You should use sqrt(CheckF) since there is a dedicated function in C for square roots! The following works for me so if you fix the above two problems, your code will probably work.
int main() {
double A1, A2, A, B, C, ans, Z;
printf("Welcome to Quadratic Equation solver. Enter the coefficient of X^2, followed by\nthe coefficient of X, followed by the integer value.\n\nEnter values: ");
A = 3;
B = 32;
C = 2;
double CheckF = (B * B - 4 * A * C);
if (CheckF >= 0) {
Z = sqrt(CheckF);
A1 = (-B + Z) / (A + A);
A2 = (-B - Z) / (A + A);
if (A1 == A2) {
ans = A1;
printf("\nRoot of equation is %f (Repeated root)\n", ans);
} else if (A1 != A2) {
printf("Roots of equation are %f and %f \n", A1, A2);
}
}
}

Why is my Taylor series for calculating cosine inaccurate for some inputs?

I am evaluating value of cos(x) using the Taylor's series which calculates the series up to n terms where n is entered by user.
I am getting correct output for some values (correct up to 4 decimal places, which is very nice) but I am also getting hugely erroneous outputs for some values of x.
Please see my code and tell me what is exactly going wrong here.
input x=0.5 n=10, output cos(x) = 0.877583, which is correct.
input x=-0.8 n=7, output cos(x) = 0.696707, again correct.
input x=5 n=10, output cos(x) = 0.283625, correct.
input: x=10 n=10 output: cos(x) = -34.438612 huge inaccuracy
double x, t=1,s=1;
int i,n;
printf("Enter x\n");
scanf("%lf",&x);
printf("Enter n");
scanf("%d",&n);
for(i=1;i<n;i++){
t*=(-x*x)/((2*(i-1)+2)*(2*(i-1)+1));
s+=t;
}
printf("\n %lf \n", s);
Why is my Taylor series for calculating cosine inaccurate for some inputs?
It has been a while, but I am pretty sure that the domain of x is {0..2} for this calculation, as x is in radians.
A test you can add inside your loop is:
if (s < -1 || s > 1) {
fprintf(stderr, "Range error!: %le\n", s);
exit(1);
}
Also, if you have a unix-y system, here is your program in bc, which does not rely on float point approximation:
scale=20
define t(x,n) {
auto i, s, t
s = 1
t = 1
for (i=1; i<n; i++) {
t*=(-x*x)/((2*(i-1)+2)*(2*(i-1)+1))
s+=t
if (s < -1 || s > 1) {
"range error!\n"; return s
}
}
return s
}
You can run this interactively with bc filename, then type in your examples like t(8, 10).
As for whether the sequences converge for all values of x; my math is probably not good enough to answer that. That is why I chose programming, math is hard.
However, here is a cosine definition from an old systems bclib.b:
define c(x) {
auto a, b, c, d, e, g, y;
y = - x*x;
a = 1;
b = 1;
c = b;
d = 1;
e = 1;
for (a=2; 1 == 1; a += 2) {
b *= y;
c = c*a*(a-1) +b;
d *= a*(a-1);
g = c/d;
if (g == e) return (g);
e = g;
}
}
Which is slightly different from yours, yet does seem to work for any range of input. So, you might want to take a look at what is different....
(note that in bc, the variable scale holds the precision the calculator is working in; so c(8,10) is scale=10; c(8)

Rotation program in C

I'm basically trying to make a math rotation program in C. But the output is always wrong. P(x,y) is rotated about Q(r,s); clockwise (direction=1) or anticlockwise (direction=0). The a,b,c are angles in triple ,I guess question meant c is in hundred's then b is in ten's and a is unit's.
Input:
0
7 3
0 1 1
0 0
Output: -3 7
Whereas I'm getting -5 5.
Thanks for your time if you help me.
Original question link: https://www.codechef.com/problems/DSPC305
i found another question by the same uploader which uses TRIPLE too. He further added a note :Triple is defined by a,b,c where a is base, b is height and c is hypotenuse of a triangle. Each triple corresponds to an angle given by cosA= a/c
#include<stdio.h>
#include<math.h>
int main() {
int x,y,a,b,direction,c,r,s,xnew,ynew;
scanf("%i", &direction);
scanf("%i %i", &x, &y);
scanf("%i %i %i" , &a, &b, &c);
scanf("%i %i", &r, &s);
float PI = 3.1415926535897932384626;
float theta = ((c*100+b*10+a)*PI)/180;
if (direction==1)
{
xnew= (x-r) * cos(theta) + (y-s) * sin(theta);
ynew= -(x-r) * sin(theta) + (y-s) * cos(theta);
printf("%i %i", xnew+r, ynew+s);
}
if (direction==0)
{
xnew =( (x-r) * ((cos(theta))) - (y-s) * sin(theta));
ynew =( (x-r) * ((sin(theta))) + (y-s) * cos(theta));
printf("%i %i", (xnew+r), (ynew+s));
}
return 0;
}
This
float theta = ((c*100+b*10+a)*PI)/180;
has nothing to do with the definition of a triple.
You can use this code:
#include<stdio.h>
#include<math.h>
int main()
{
double xp,yp,xq,yq,a,b,c;
double t,xn,yn;
int z;
scanf("%d",&z);
scanf("%lf%lf",&xp,&yp);
scanf("%lf%lf%lf",&a,&b,&c);
scanf("%lf%lf",&xq,&yq);
t=asin(b/c);
if(z==0)
{
xn=xp*cos(t)-yp*sin(t)-xq*cos(t)+yq*sin(t)+xq;
yn=xp*sin(t)+yp*cos(t)-xq*sin(t)-yq*cos(t)+yq;
}
else
{
xn=xp*cos(t)+yp*sin(t)-xq*cos(t)-yq*sin(t)+xq;
yn=-xp*sin(t)+yp*cos(t)+xq*sin(t)-yq*cos(t)+yq;
}
printf("%0.lf %0.lf",xn,yn);
return 0;
}
This code gave correct output for both of the test cases provided in the question.
Do tell if it worked :)

Command Line Arguments in C Returning Large Numbers

I am writing a basic program to calculate an arithmetic-geometric mean using command line arguments using C. However the program doesn't seem to be recognizing anything I type in. Here is my code:
/*
*This program will calculate an arithmetic-geometric mean
*provided two numbers (x,y) and an epsilon (e) are entered.
*/
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
int main (int argc, char **argv) {
//Check for command line argument.
if (argc != 4) {
printf ("Please enter two numbers (x,y) and an epsilon (e)\n");
printf ("as command line arguments for an AGM calculation\n");
exit(1);
}
double e,x,y,an,gn;
x = atof (argv[1]); //First number x.
y = atof (argv[2]); //Second number y.
e = atof (argv[3]); //Number of repetitions e.
double absoluteAnMinusGn; //Continuation condition.
double a = (x + y) / 2; //Normal arithmetic mean.
double g = sqrt (x * y); //Normal geometric mean.
an = (a + g) / 2; //Iteration 1 for calculation arithmetic mean.
gn = sqrt (a * g); //Iteration 1 for calculation geometric mean.
absoluteAnMinusGn = an - gn; //Calculates continuation condition.
if (absoluteAnMinusGn < 0) {
absoluteAnMinusGn = absoluteAnMinusGn * (-1); //Ensures absolute value of continuation condition.
}
printf ("DEBUG IN: x%d, y%d, e%d, absoulteAnMinusGn%d, a%d, g%d, an%d, gn%d\n", x,y,e,absoluteAnMinusGn,a,g,an,gn);//DEBUG CODE
while (absoluteAnMinusGn > e) {
an = (a + g) / 2;
gn = sqrt (a * g);
a = an;
g = gn;
absoluteAnMinusGn = an - gn;
if (absoluteAnMinusGn < 0) {
absoluteAnMinusGn = absoluteAnMinusGn * (-1);
}
}
//printf ("The arithmetric-geometric mean is (%d,%d) for %d\n", a,g,e);
printf ("DEBUG OUT: x%d, y%d, e%d, absoulteAnMinusGn%d, a%d, g%d, an%d, gn%d\n", x,y,e,absoluteAnMinusGn,a,g,an,gn);//DEBUG CODE
return 0;
}
I enter the following on the command line: agm.exe 3 4 5
I get the following output:
DEBUG IN: x0, y10742661112, e0, absoluteANMinusGn1074790400, a0, g1075052544, an-171951648, gn1057505593
DEBUG OUT: x0, y10742661112, e0, absoluteANMinusGn1074790400, a0, g1075052544, an-171951648, gn1057505593
I made a similar program yesterday for calculating an integral using command line inputs that works exactly as intended. The code for that is here:
/*
*This program will calculate a Riemann sum using the
*left hand rule for sin(x)/x.
*/
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
int main (int argc, char **argv) {
//Check for command line argument.
if (argc != 4) {
printf ("Please enter integral bounds (a,b) and number of intervals (n)\n");
printf ("as command line arguments for a Riemann sum calculation \n");
exit(1);
}
double a,b,i,n,h,riemann,rectangles,answer;
a = atof (argv[1]); //Lower bound of integral.
b = atof (argv[2]); //Upper bound of integral.
n = atof (argv[3]); //Number of intervals.
h = (b - a) / n; //Delta X.
i = 0; //Counts intervals.
//Calculation of Left Hand Riemann Sum.
while (i <= (n - 1)) {
if (a == 0 && i == 0) { //Stops from dividing by zero.
rectangles = 1;
i++;
}
riemann = (sin(a + (i * h))) / (a + (i * h));
rectangles += riemann;
i++;
}
//Finalize answer.
answer = rectangles * h;
printf ("Sin(x)/x for bounds (%f , %f) with %f intervals is approximately %f \n", a,b,n,answer);
return 0;
}
The above program for a left hand Riemann sum outputs correctly, and is almost the same as the code I have for the AGM. Can someone please help me figure out what is going wrong here? I've searched all over and I can't find a solution. I'm aware that the AGM code is probably set up to output an incorrect answer, but my primary concern is fixing my command line argument recognition. I can redo my math later.
The format specifier for printing double is %f. In cases where you didn't provide the right format specifier to process the double, and passed double to %d format specifier - it lead to undefined behavior.(%d expect integral argument not double) (in your case wrong output).
From ยง7.21.6.3p9 N1570 (c11 standard)
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
I did not test your algorithm, but I found at least three problems in your code. I now list them as follows:
Forgot init your variable, that's why you got a Large Numbers
which is memory undefined data!
No have covert your argv to a integer type.
Wrong format for printf.
I have put my fixed code here, you can test it . if it can run as your expect!
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
int main (int argc, char *argv[]) {
if (argc != 4) {
printf ("Please enter two numbers (x,y) and an epsilon (e)\n");
printf ("as command line arguments for an AGM calculation\n");
exit(1);
}
// argv is pointer which pointer to pointer
// and argv[1] is a pointer to a string.
// so we need to covert string to int
char *p=NULL;
int x = strtol(argv[1], &p, 10);
int y = strtol(argv[2], &p, 10);
int e = strtol(argv[3], &p, 10);
//Check for command line argument.
double an = 0.0,gn =0.0;
double absoluteAnMinusGn=0.0; //Continuation condition.
double a = (x + y) / 2; //Normal arithmetic mean.
double g = sqrt (x * y); //Normal geometric mean.
an = (a + g) / 2; //Iteration 1 for calculation arithmetic mean.
gn = sqrt (a * g); //Iteration 1 for calculation geometric mean.
absoluteAnMinusGn = an - gn; //Calculates continuation condition.
if (absoluteAnMinusGn < 0) {
absoluteAnMinusGn = absoluteAnMinusGn * (-1); //Ensures absolute value of continuation condition.
}
printf ("DEBUG IN: x%d, y%d, e%d, absoulteAnMinusGn=%f, a=%f, g=%f, an=%f, gn=%f\n", x,y,e,absoluteAnMinusGn,a,g,an,gn);//DEBUG CODE
while (absoluteAnMinusGn > e) {
an = (a + g) / 2;
gn = sqrt (a * g);
a = an;
g = gn;
absoluteAnMinusGn = an - gn;
if (absoluteAnMinusGn < 0) {
absoluteAnMinusGn = absoluteAnMinusGn * (-1);
}
}
printf ("DEBUG OUT: x=%d, y=%d, e=%d, absoulteAnMinusGn=%f, a=%f, g=%f, an=%f, gn=%f\n", x,y,e,absoluteAnMinusGn,a,g,an,gn);//DEBUG CODE
return 0;
}
and then when i run it with some sample number like below show, i got the result .
Just replace the %d(which is a format specifier for integers) with %f(which is the format specifier for double) because you are using a variable of type double, not an integer .

3-digit integer number program won't execute

Yes, this is a basic C coding homework problem. No, I am not just looking for someone to do it for me. Considering that this is my first programming class, I'm not surprised that I can't get it to work, and I'm certain there is plenty wrong with it. I just want some help pointing out the problems in my code and the things that are missing so that I can fix them on my own.
Homework Question:
Write a program to read ONLY one integer number (your input must be
one 3 digit number from 100 to 999), and to think of a number as
being ABC (where A, B, and C are the 3 digits of a number). Now,
form the number to become ABC, BCA, and CAB, then find out the
remainder of these three numbers when they are divided by 11.
Assume remainders would respectively be X, Y, and Z and add them
up as X+Y, Y+Z, and Z+X. Now if any of these summations is odd
number, increase it by 11 if the summation plus 11 is less than 20,
otherwise decrease the summation by 11 (this summation operation
must be positive number but less than 20). Finally, divide each
of the sums in half. Now, print out all the resulting digits.
My Code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Declare all variables
int OrigNumber;
int x, y, z;
int number;
number = x, y, z;
int sum;
//
printf("Input a three digit number");
//
int c;
c = OrigNumber %10;
//
int b;
b=((OrigNumber - c) % 100)/10;
//
int a;
a = (OrigNumber - (b + c))/100;
//
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
//
if((number % 2) == 1)
{
if(number + 11 < 20)
number += 11;
else if((100 - 11 > 0) && (100 - 11 < 20))
number -= 11;
}
//
x = abc/11;
y = bca/11;
z = cab/11;
//
sum = (x + y),
(y + z),
(z + x);
}
To start with, you need to read the input. Start with a prompt that includes a carriage return:
printf("Input a three digit number: \n");
Since it's a three digit number, you could add the following line to read the input:
scanf("%3d", &OrigNumber);
The next bit of code works quite well until you get to your if (number % 2) which is meaningless since you didn't really define number - well, you did, but the line
number = x, y, z;
does NOT do what you think it does. If you add
printf("So far I have abc=%d, bca=%d, cab=%d\n", abc, bca, cab);
after you first read in the number and computed those three, you will see you are well on your way.
Note that
number = x, y, z;
Uses a thing called the "comma operator". All the things (a,b,c) are "evaluated" but their values are not returned. At any rate, where you have that line, you didn't yet assign a value to x,y and z.
Is that enough to get your started?
update now that you have had a few hours to mull this over, here are a few more pointers.
Your computation of abc, cab, bca makes no sense. I will show you just one of them:
cab = c*100 + a*10 + b;
Next you need to compute each of x, y and z. Again, here is one of the three:
y = bca%11;
Now you have to make the sums - I call them xy, yz, and zx. Just one of them:
zx = z + x;
Next, to deal with the instruction: "Now if any of these summations is odd number, increase it by 11 if the summation plus 11 is less than 20, otherwise decrease the summation by 11:
if(xy % 2 == 1) {
if(xy + 11 < 20) xy += 11; else xy -= 11;
}
use similar code for all three sums. Then "divide by 2":
xy /= 2;
repeat as needed.
Finally, print out the result:
printf("xy: %d, yz: %d, zx: %d\n", xy, yz, zx);
The amazing thing is that if you did this right, you get the original numbers back...
You could make the code more compact by using an array of values and looping through it - rather than repeating the code snippets I wrote above with different variables. But I suspect that is well outside the scope of what you are expected to know at this point.
Can you take it from here?
#include <stdio.h>
int main()
{
//Declare all variables
int OrigNumber;
int a, b, c;
int abc, bca, cab;
int x, y, z;
int xplusy , yplusz, xplusz;
printf(" A program to read ONLY one integer number.\n Input must be one 3 digit number from 100 to 999 : ");
scanf("%d", &OrigNumber); // Get input from console
if(OrigNumber > 999 || OrigNumber < 100) {
printf("Invalid number. Quiting program. This is error handling. Important while learning programming.");
return 0;
}
c = OrigNumber %10; // digit at unit's place
b=((OrigNumber) % 100)/10; //digit at the ten's place
a = (OrigNumber)/100; //digit at the 100's place. Note: 734/100 = 7. NOT 7.34.
printf("\n Three numbers say A,B, C : %d, %d , %d ", a, b, c);
abc = a*100 + 10*b + c;
bca = 100*b + 10*c + a;
cab = c*100 + a*10 + b;
printf("\n Three numbers say ABC, BCA, CAB : %d, %d , %d ", abc, bca, cab);
x = abc % 11; // Reminder when divided by 11.
y = bca % 11;
z = cab % 11;
printf("\n Three numbers say X, Y, Z : %d, %d , %d ", x, y, z);
xplusy = x + y; // Adding reminders two at a time.
yplusz = y + z;
xplusz = x + z;
printf("\n Three numbers X+Y, Y+Z, X+Z : %d, %d , %d ", xplusy, yplusz, xplusz);
if((xplusy % 2) == 1) {
if(xplusy + 11 < 20)
xplusy += 11;
else
xplusy -= 11;
}
if((yplusz % 2) == 1) {
if(yplusz + 11 < 20)
yplusz += 11;
else
yplusz -= 11;
}
if((xplusz % 2) == 1) {
if(xplusz + 11 < 20)
xplusz += 11;
else
xplusz -= 11;
}
xplusy /= 2; // Finally, divide each of the sum in half.
yplusz /= 2;
xplusz /= 2;
printf("\n Now print out all the resulting digits : %d, %d , %d \n", xplusy, yplusz, xplusz);
return 0;
}
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
I suggest printing out the numbers at this point in the code.
printf( "%d %d %d", abc, bca, cab );
I think you'll see one of the problems you need to solve.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int n, a, b, c, abc, bca, cab, x, y, z, p, q, r;
scanf("%d", &n);
c=n%10;
b=(n/10)%10;
a=n/100;
abc=a*100+b*10+c;
bca=b*100+c*10+a;
cab=c*100+a*10+b;
x=abc%11;
y=bca%11;
z=cab%11;
p=x+y;
q=y+z;
r=z+x;
return 0;
}
Now if any of these summations is odd number, increase it by 11 if the
summation plus 11 is less than 20, otherwise decrease the summation by
11 (this summation operation must be positive number but less than
20). Finally, divide each of the sums in half. Now, print out all the
resulting digits.
i didnt get the final part, can you explain it more clearly?

Resources