-3

I'm doing a science fair project that tests five different square root algorithms to compute the square root of two. (see my question here).

I have two options.

  • Run each program for a set amount of time, and compare how close the end result is with the square root of two.
  • Run each program until the square root of two is accurate to fifty decimal places, and compare the time taken using System.nanoTime()

The downside of the second one is that the mere process of checking whether it is accurate to fifty decimal places at each iteration takes some time, so the results won't be accurate. If there is some other way to do this, please inform me

The downside of the first one is that I don't know how to run a program for a set amount of time.

Which course of action should I take?

Community
  • 1
  • 1
  • 4
    Please show us your effort until now - what you have attempted to solve the problem. – Lion Oct 14 '13 at 19:36
  • (Sideways thought) Calculate your root once and then check its digits one thousand times. Divide that time by 1,000 and you know how much the checking costs. (About-ish. Beware of caching issues -- you do *not* want to compare a single run of either with eachother.) – Jongware Oct 14 '13 at 19:38

3 Answers3

0

I don't know how to run a program for a set amount of time.

One option is to run the code that needs to run for x time in a thread.
Terminate the thread when the time is up and then have the thread code to present its result.
Something like this.

import java.io.*;
public class SqrtThread extends Thread{
  private vars.....
  public SqrtThread (double input) { 
    super('sqrtThread');
    this.input = input;
    ....
    this.start();
  }

  public void run() {
    while !(Thread.interrupted) {   
      //Do numberChruching
    }
    //output result
  }           
}

Then you start the Thread using pseudo code like:

SqrtThread sqrtThread = new SqrtThread(2); //Will start automatically
start high resolution timer
while (time has not elapsed) {
  sleep for very short period;
}
sqrtThread.interrupt(); //stop the thread.

How you actually do the very short sleep is part of the assignment so I'll leave that for you to find out.

Johan
  • 74,508
  • 24
  • 191
  • 319
0

The amount of time consumed by the test will be the same for each method. Hence, if you are interested in a comparison, this is not a disadvantage. Also, I would suspect that the time consumed by the test is no significant.

In addition: you need such a test anyway. Usually one is interested in a result up-to a given error. Not in an unknown accuracy obtained in a known time since the time needed depends on a lot of other stuff (CPU, JVM, etc). From this is vote for the second approach.

Christian Fries
  • 16,175
  • 10
  • 56
  • 67
0

If you do a set amount of time, and then interrupt the process, you have an interesting question to answer:

  • Did you collect enough data to answer the question?

I'll let you ponder that question, while I suggest how you could interrupt a still-calculating answer.

First, you should know ahead of time the first fifty digits of your square root, as you will need that to "know" if the answer is correct. Correctness should be independent of how long it takes, so perhaps you'll just verify the calculation once, and then hard-code the correct answer.

Second, you need to package your square root calculation algorithims in something that can be run. I would suggest that Java interface Runnable, which forces a method with the signature

public void run() {
  // your code goes here
}

Then you will have something that will blend well with a Java Thread and you can interrupt Java threads. Once interrupted the results of a Thread, you cannot trust any calculation from within the thread (under normal circumstances).

The simplest means (and since your project is not about leveraging the newest Java technologies, but about attempting to disprove your anti-hypothesis) is to do something like

Thread solution1 = new Thread(new Runnable1());
solution1.start();

later if you find something is taking far too long

Thread.sleep(10000);  // sleeps the current thread 10 seconds
solution1.interrupt();

Note that this is a very inelegant way to stop a thread, and you can't trust anything that the Runnable1 was working on afterwards.

Other, more sophisticated techniques are available, such as:

public class Runnable1 implements Runnable {

  private boolean running;

  public Runnable1() {
    running = false;
  }

  public void run() {
    running = true;
    while (running) {
      // do one step of your computation
    }
  }

  public void shutdown() {
    running = false;
  }
}

The above example has tons of features which really do improve the quality of the Java code; but, be aware that quality of code is independent of proving your point. It is possible to polish code to be very nice, and forget to actually solve the problem.

The above code would then be called

Runnable1 runnable1 = new Runnable1();
Thread thread1 = new Thread(runnable1);
thread1.start

// some means of waiting
Thread.sleep(10000); // sleeps 10 seconds
runnable1.shutdown();

This technique shuts down your runnable in a known state (before the next loop iteration), and so perhaps you could then capture some intermediate data from the technique, provided that the rest of the Runnable has a means to report an intermediate solution.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • To start, I would avoid extending the `Thread` class, as if you ever decide to use some of the nicer concurrency features of Java, you will have to "unwrite" that code anyway. – Edwin Buck Oct 14 '13 at 20:27