This is one of my classes that I am testing. It keeps failing the calculateVolume() method and I am not sure why.
package shape3D;
public class Sphere implements Cloneable {
private double myRadius;
private double myVolume;
private double mySurfaceArea;
private final static double pi = 3.14;
public static void main(String args[]){
Sphere sphere = new Sphere();
}
public double calculateVolume(){
myVolume = (4/3)*pi*(Math.pow(myRadius,3));
return myVolume;
}
public double calculateSurfaceArea(){
mySurfaceArea = ((4)*(pi)*(Math.pow(myRadius,2)));
return mySurfaceArea;
}
public double getSurfaceArea(){
return this.calculateSurfaceArea();
}
public double getVolume(){
return this.calculateVolume();
}
public void setRadius(double radius2){
myRadius = radius2;
}
public String toString(){
return "Volume: " + this.getVolume() + " Surface area " + this.getSurfaceArea();
}
public Sphere clone (){
Sphere p = new Sphere();
p.setRadius(myRadius);
return p;
}
}
Here is the JUnit test case I am using
public class sphereTest {
#Test
public void testSphere(){
shape3D.Sphere sphere = new shape3D.Sphere();
sphere.setRadius(6);
assertTrue(sphere.calculateSurfaceArea()== 452.16);
assertTrue(sphere.calculateVolume()== 904.32);
The calculateSurfaceArea() stuff passes fine but the volume is failing and I am not sure why.
The calculation
myVolume = (4/3)*pi*(Math.pow(myRadius,3));
Uses integer arithmetic: 4/3 evaluates to 1.
Change it to
myVolume = (4.0/3)*pi*(Math.pow(myRadius,3));
You're doing integer division when calculating the volume truncating the first term of the equation to 1. Replace
myVolume = (4 / 3) * pi * (Math.pow(myRadius, 3)); // 678.24
with
myVolume = (4 / 3.0) * pi * (Math.pow(myRadius, 3)); // 904.31
Due to floating point imprecision you will still need to allow for the difference between the expected & calculated values. You can use this version of assertEquals which allows a delta value to do the comparison - replace
assertTrue(sphere.calculateVolume()== 904.32);
with
assertEquals(sphere.calculateVolume(), 904.32, .02);
Quite aside from the 4/3 integer problem (which I failed to spot): It's not safe to compare two Java double values this way.
If you use assertEquals instead of assertTrue then you might see the problem. I'm betting that it's calculating 4/3 first, then truncating it. And it'll still do this even if you make those into doubles.
Use the overload for assertEquals as mentioned in this question.
Related
I'm trying to write a java program that will solve any ordinary differential equations using Euler method, but I don't know how to write a code to get any differential equation from the user. I was only able to write the code to solve a predefined ordinary differential equations.
I was able to come with a code to solve some particular ordinary differential equations which were written as functions in the program, I also made research online to look for similar problems but it seem they also wrote it to solve some designated problem not general questions on ordinary differential equations. This was found in most of the article have read online.
Here is my Euler class;
import java.lang.Math;
public class Euler {
private double x0, y0, x1, y1, h, actual;
public Euler (double initialx, double initialy,double stepsize,double finalx1) {
x0 = initialx; y0 = initialy; h=stepsize; x1 = finalx1;
}
public void setEuler (double initialx, double initialy,double stepsize,
double finalx1){
x0 = initialx;y0 = initialy;h =stepsize;x1 = finalx1;
}
public double getinitialx(){
return x0;
}
public double getinitialy(){
return y0;
}
public double getinitialexact(){
return (double) (0.9048*Math.exp(0.1*x0*x0));
}
double func(double x, double y){
return (double) (0.2*x*y);
}
double funct(double x){
return (double) (java.lang.Math.exp(0.1*x*x));
}
public double getinitialerror(){
return (double) Math.abs(actual - y0);
}
public double getEulerResult(){
for (double i = x0 + h; i < x1; i += h){
y0 = y0 + h *(func(x0,y0));
x0 += h;
double actual = (0.9048*funct(x0));
double error = Math.abs(actual - y0);
System.out.printf("%f\t%f\t%f\t%f\n",x0,y0,actual, error);
}
return y0;
}
}
Here is my Driver's class
import java.util.Scanner;
public class EulerTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Euler myEuler = new Euler(1.0,1.0,0.1,1.5);
System.out.println( "x\t explicit\tactual\t error\t " );
System.out.printf("%f\t%f\t%f\t%f\n", myEuler.getinitialx(),
myEuler.getinitialy(),myEuler.getinitialexact(),
myEuler.getinitialerror());
System.out.printf("my approximated value is %f\n\n",
myEuler.getEulerResult ());
System.out.println("enter another initial value of x: ");
double initialx = input.nextDouble();
System.out.println("enter another initial value of y: ");
double initialy = input.nextDouble();
System.out.println("enter another stepsize value of h: ");
double stepsize = input.nextDouble();
System.out.println("enter another upper bound of x: ");
double finalx1 = input.nextDouble();
myEuler.setEuler(initialx,initialy,stepsize,finalx1);
System.out.println( "x\t explicit\tactual\t error\t " );
System.out.printf("%f\t%f\t%f\t%f\n", myEuler.getinitialx(),
myEuler.getinitialy(),myEuler.getinitialexact(),
myEuler.getinitialerror());
System.out.printf("my approximated value is %f\n\n",
myEuler.getEulerResult ());
}
}
I will be glad if i can en lighted on how to write the java code to collect any ordinary differential equation from the user so as to solve using Euler's method.
What you are looking for is the ability to compile some code at run time, where part of the code is supplied by the user.
There is a package called JOOR that gives you a Reflect class that contains a compile method. The method takes two parameters (a package name:String and the Java code:String).
I've never personally used it, so can not vouch for its robustness, but here is a tutorial and the javadoc:
https://www.jooq.org/products/jOOR/javadoc/latest/org.jooq.joor/org/joor/Reflect.html#compile(java.lang.String,java.lang.String)
https://blog.jooq.org/2018/04/03/how-to-compile-a-class-at-runtime-with-java-8-and-9/
In your case, you would put your user supplied function in place of the following line of code:
return \"Hello World!\";\n"
Beware, you need to be 100% absolutely unconditionally guaranteed that the user can only ever enter a function to be solved. If they are supplying code, remember that unless you take safeguards, the code they enter could very easily be code the removes all of the files on your hard drive (or worse).
For the second part of your question - how do i implement a solution in Java using Euler's method, perhaps check out this link: Euler's Method in java or this https://rosettacode.org/wiki/Euler_method#Java which has it in pretty much every language you can imagine (and probably some you can't).
I'm trying to print the area and perimeter of a triangle with the given lengths. I have successfully printed the correct perimeter however, my area is incorrect (the output of the area is 0.00). I realized that it is a loss of precision error but, I am unable to solve it. Will anyone please examine this code and point out the issue, specifically at the instance method,calculateArea? Thank you.
public class Triangle
{
private int sideA=0, sideB=0, sideC=0, perimeter=0;
private double area=0;
public Triangle()
{
}
public Triangle(int a, int b, int c)
{
setSides(a,b,c);
}
public void setSides(int a,int b, int c)
{
sideA=a;
sideB=b;
sideC=c;
}
public void calculateArea()
{
int s;
s=(int)perimeter/2;
double area=Math.sqrt(s*(s-sideA)*(s-sideB)*(s-sideC));
}
public void calculatePerimeter()
{
perimeter=sideA+sideB+sideC;
}
public void printTriangle()
{
System.out.printf("The triangle with sides %d , %d and %d has an area of %.3f and perimeter %d%n", sideA, sideB, sideC, area, perimeter);
}
}
For reference(you don't need to correct it or anything), here's my other code.
public class TriangleRunner
{
public static void main(System[]args)
{
Triangle isoceles = new Triangle();
isoceles.setSides(3,3,3);
isoceles.calculateArea();
isoceles.calculatePerimeter();
isoceles.printTriangle();
Triangle right345 = new Triangle();
right345.setSides(3,4,5);
right345.calculateArea();
right345.calculatePerimeter();
right345.printTriangle();
}
}
You are using perimeter in calculateArea, but that is only calculated in calculatePerimeter, which isn't called yet, so perimiter is still 0. You can simply call calculatePerimeter first, before calling calculateArea, but it may be best to call calculatePerimeter in calculateArea to make sure it's available to you.
Because the perimeter value depends on the other values, it isn't a good idea to have it as an instance variable. You may want to return that value in calculatePerimeter, using it as a local variable when necessary.
Also, change s in calculateArea to a double, and divide by the double literal 2.0 instead of 2, to force floating-point calculations.
With these changes I get correct output.
I am encountering a problem when creating a program to solve simple kinematics.
I run the program and find out the fields haven't been modified properly . Here is
the scrap of my program that initialise the object and setting the variables.
public class LinearConstantAcceleration1DKinematics {
private double distance;
private double speed;
private double acceleration;
private double time;
public LinearConstantAcceleration1DKinematics() {
/* initialize the object */
distance = 0;
speed = 0;
acceleration = 0;
time = 0;
}
public void setS(double s) {
this.distance = s;
}
//continue with 3 more setters which is created in the same way ,i have omitted them here
public double getU(){
double u_ans;
u_ans = (distance - 1/2 *acceleration*time*time )/time;
return u_ans;
}
}
And here is the main that uses the methods
LinearConstantAcceleration1DKinematics kinematics = new LinearConstantAcceleration1DKinematics();
kinematics.setS(175);
kinematics.setA(10);
kinematics.setT(5);
System.out.printf(%f\n", kinematics.getU());
The result is 35 which is incorrect.Many thanks for your help.
This has absolutely nothing to do with setter methods -- your division is wrong since 1 / 2 does int division and returns 0 resulting in the equation calculating simply distance / time.
Change to:
u_ans = (distance - 1.0 / 2.0 * acceleration * time * time) / time;
Lesson to learn: don't assume where the error is -- test it. Use a debugger or println statements to check the states of your variables as your program runs.
I have to make an implementation to calculate volume of a sphere to be checked with JUnit test, but there are some errors. The formula is correct, but when I test it, it doesn't work :
class VolumeSphere.java
public class VolumeSphere {
public static double volsph(double j) {
double volume;
double const = 1.33;
double phi = 3.14;
volume = const * phi * (j * j * j);
return volume;
}
}
and then this the test file :
VolumeSphereTest.java
import junit.framework.*;
public class VolumeSphereTest extends TestCase {
public VolumeSphereTest(String name) {
super(name);
}
public void testSimple() {
assertEquals(33.4096, VolumeSphere.volsph(2.0));
}
}
when I run the JUnit test, it's said "Expected: (33.4096) but was: (33.4096000005)."
So, what should I do? Thankyou in advance for the help!
The problem is that 33.4096 isn't exactly represented by a double, nor is 1.33, and nor is 3.14. Moreover, the multiplication introduces its own errors. Therefore, the assertEquals needs to be replaced by something that basically means "assert that the value is very close to what we expect".
JUnit has assertEquals(expectedValue, actualValue, errorPermitted) for comparing doubles, which is what you should use here.
In general, double is a poor choice of data type for doing exact arithmetic with numbers expressed as decimals, because it stores binary representations of numbers. If you want accuracy with exact decimals, use BigDecimal instead.
const is a keyword and can't be a name of a variable - pick a different name for your variable.
The problem is that the answer isn't exactly the value you let the JUnit test compare to. The answer is 33.409600000000005 instead of 33.4096. To remedy this, you could use assertEquals(33.4096, VolumeSphere.volsph(2.0), 0.0001);.
This will allow all answers within a difference of 0.0001 around 33.4096. Therefor in this case it will allow 33.4095 to 33.4097.
Also, instead of using double phi = 3.14, you could use Math.PI, which inserts the more significant value of constant pi.
I have a very simple piece of code below which I think gives the wrong result from a user's perspective.
package com.test.sample;
public class Test {
public static void main(String[] args) {
float c,d;
c = (float) 12.47;
d = (float) 12.44;
d = c - d;
System.out.println("Hello the calculated value of a=" + d);
}
}
The output is
Hello the calculated value of a=0.030000687
But I want a=0.030000000 which is the perfect value.
Floating point arithmetic, what developers should know.
The JVM implements the IEEE-754 1985 floating point standard and it has its accuracy problem (since floating point numbers cannot precisely represent all real numbers).
If you seek accuracy, use java.math.BigDecimal object instead.
Update: This is how I took your example and used BigDecimal to achieve your expected result:
import java.math.BigDecimal;
/**
* #author The Elite Gentleman
*
*/
public class BigDecimalTest {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BigDecimal a = new BigDecimal(Float.toString(12.47f));
BigDecimal b = new BigDecimal(Float.toString(12.44f));
BigDecimal c = a.subtract(b);
System.out.println(c);
}
}