System.nanoTime测量牛顿迭代

时间:2013-11-02 17:00:07

标签: debugging zero square-root

我使用以下程序来测量计算机进行牛顿迭代计算2到50个小数位的平方根所需的时间。

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());
}
}

然而,当我运行它时,它会显示0.出了什么问题?

1 个答案:

答案 0 :(得分:0)

System.nanoTime()提供纳秒分辨率的可能性,但不是保证。

  

此方法提供纳秒精度,但不一定   纳秒分辨率(即,值的变化频率) - 否   除了分辨率至少与分辨率一样好之外,还要做出保证   currentTimeMillis()。

因此,如果a = a.add(two.divide(a)).divide(two);花费不到一毫秒(并且它会),测量的准确性将取决于您的操作系统和JVM实现。

如果您确实使用BigDecimal(尽管您不需要),请不要在System.nano次调用之间运行BigDecimal构造函数,除非您想在测量中包含它。

编辑:我的建议:

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
    }
}