Question

I used the following program to try to measure the amount of time taken for the computer to do the newton Iteration to compute the square root of two to 50 decimal places.

import java.math.BigDecimal;
public class ScienceFair {

public static BigDecimal NewtonMethod()
{
    BigDecimal a = new BigDecimal(1);
    BigDecimal btime = new BigDecimal(0);
    BigDecimal etime = new BigDecimal(0);
    BigDecimal time = new BigDecimal(0);
    BigDecimal two = new BigDecimal(2);
    while(a.subtract(new BigDecimal("1.41421356237309504880168872420969807856967187537694")).abs().scaleByPowerOfTen(50).doubleValue() < 1)
    {
    btime = BigDecimal.valueOf(System.nanoTime()*1000000000);
    a = a.add(two.divide(a)).divide(two);
    etime = BigDecimal.valueOf(System.nanoTime()*1000000000);
    time = time.add(etime.subtract(btime));
    }
    return time;
}
public static void main(String[] args) {
    System.out.print(NewtonMethod().toString());
}
}

When I run it, however, it displays 0. What is wrong?

Was it helpful?

Solution

System.nanoTime() provides the possibility of nanosecond resolution, but not the guarantee.

This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis().

So, if a = a.add(two.divide(a)).divide(two); take less than a millisecond (and it will), the exactness of the measurement will depend on your OS and the JVM implementation.

If you do use BigDecimal (though you don't need to), don't run the BigDecimal constructor in between your System.nano calls, unless you want to include that in your measurement.

EDIT: My suggestion:

import java.math.BigDecimal;
public class ScienceFair {

    private static long NewtonMethod() {
        BigDecimal TWO = new BigDecimal(2);
        BigDecimal SQRT_TWO = new BigDecimal("1.41421356237309504880168872420969807856967187537694");
        BigDecimal TOLERANCE = BigDecimal.ONE.scaleByPowerOfTen(-50);

        long start = System.nanoTime();

        BigDecimal a = new BigDecimal(1);
        BigDecimal two = new BigDecimal(2);
        while(a.subtract(SQRT_TWO).abs().compareTo(TOLERANCE) >= 0) {
            a = a.add(TWO.divide(a)).divide(TWO);
        }

        return System.nanoTime() - start;
    }

    public static void main(String[] args) {
        System.out.println(NewtonMethod() / 10e6); //# of milliseconds
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top