1

我使用以下程序来尝试测量计算机执行牛顿迭代以计算 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。出了什么问题?

4

1 回答 1

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
    }
}
于 2013-11-02T17:03:52.240 回答