Reputation: 31
I'm in an intro to Java course and my assignment is to write a program that takes in 3 sides of a triangle and returns the type as well as the area. The sides have to be integers according to the assignment sheet so it's proving to be a pain testing it and coming up with integer ratios to match each type.
Anyway, the real problem I'm having is sometimes it gives me the correct area and sometimes it doesn't. 6/8/10 for example returns an area of 0.
Any ideas/general tips to improve the source? Kind of seems like spaghetti to me so far but I'm a little limited in that I'm only allowed to use what we covered in class so far.
package trianglesides;
import javax.swing.*;
/*
This program will receive three numbers from a user describing the lengths of
the sides of a triangle. It will return and display the type of triangle and
the area.
*/
public class triangle_Sides {
public static void main(String[] args) {
int side1 = Integer.parseInt(JOptionPane.showInputDialog
("Enter the integer length of side 1"));
int side2 = Integer.parseInt(JOptionPane.showInputDialog
("Enter the integer length of side 2"));
int side3 = Integer.parseInt(JOptionPane.showInputDialog
("Enter the integer length of side 3"));
int s = (side1 + side2 + side3)/2;
double area = Math.sqrt(s*(s-side1)*(s-side2)*(s-side3));
if (side1 >= (side2 + side3) ||
side2 >= (side1 + side3) ||
side3 >= (side1 + side2)) {
JOptionPane.showMessageDialog(null, "That's no triangle.");
}
else {
/*Equilateral*/
if ((side1 == side2) && (side2 == side3)) {
JOptionPane.showMessageDialog(null, "This is an equilateral triangle with an area of " + area);
}
/*Right and isosceles*/
else if ((side1*side1) == ((side2*side2) + (side3*side3)) ||
(side2*side2) == ((side1*side1) + (side3*side3)) ||
(side3*side3) == ((side2*side2) + (side1*side1))) {
if (side1 == side2 ||
side2 == side3 ||
side3 == side1){
JOptionPane.showMessageDialog(null, "This is right and isosceles triangle with an area of " + area);
}
else {
JOptionPane.showMessageDialog(null, "This is a right triangle with an area of " + area);
}
}
/*Obtuse and isosceles*/
else if ((side1*side1) > ((side2*side2) + (side3*side3)) ||
(side2*side2) > ((side1*side1) + (side3*side3)) ||
(side3*side3) > ((side2*side2) + (side1*side1))) {
if (side1 == side2 ||
side2 == side3 ||
side3 == side1){
JOptionPane.showMessageDialog(null, "This is obtuse and isosceles triangle with an area of " + area);
}
else {
JOptionPane.showMessageDialog(null, "This is an obtuse triangle with an area of " + area);
}
}
/*Acute and isosceles*/
else if ((side1*side1) < ((side2*side2) + (side3*side3)) ||
(side2*side2) < ((side1*side1) + (side3*side3)) ||
(side3*side3) < ((side2*side2) + (side1*side1))) {
if (side1 == side2 ||
side2 == side3 ||
side3 == side1){
JOptionPane.showMessageDialog(null, "This is acute and isosceles triangle with an area of " + area);
}
else {
JOptionPane.showMessageDialog(null, "This is an acute triangle with an area of " + area);
}
}
}
}
}
Upvotes: 0
Views: 910
Reputation: 11776
This is happening because the variable s cannot be integer type
Change
int s = (side1 + side2 + side3)/2;
to
double s = (side1 + side2 + side3)/2.0;
Upvotes: 1
Reputation: 14215
int s = (side1 + side2 + side3)/2;
Integer roundoff will round halves down. That's not what you want. Divide by 2.0
and put the result in a double
instead.
Math.sqrt(s*(s-side1)*(s-side2)*(s-side3))
You're doing this product in integer arithmetic, which will wrap around rather than lose precision. That's not what you want. Also, this is famously not the expression of Heron's formula you want on computers.
For the bunch of comparisons, you could do better by sorting the sides in order first. Other than that, it looks like pretty reasonable code to me. You might think about keeping the "read input and do output" part separate from the "do calculations" part so that you can more easily debug and test the calculations.
Upvotes: 1