为什么对于较大的数字,平方根计算较慢?

时间:2013-07-31 15:15:16

标签: java

这是一个Java代码,要求输入一个数字,然后不使用Math.sqrt()方法打印其平方根:

import java.util.Random;
import java.io.*;
public class Square {
    public static void main(String[] args) throws IOException {
        final double TOL = 0.5E-15;
        InputStreamReader reader = new InputStreamReader(System.in);
        BufferedReader input = new BufferedReader(reader);
        System.out.print("Enter a number to get the aquare of it: ");
        double n = new Double(input.readLine()).doubleValue();
        Random random = new Random();
        double x = random.nextDouble();
        do {
            x = (x+n/x)/2;
        } while(Math.abs(x*x-n)>TOL*2*x);
        System.out.println("sqrt(" + n + ") = " + x);
    }
 }

请在您的计算机上运行并测试几个数字。 对于低于30.1的数字,它运行并快速计算平方根。但是当你输入30.2或更大的数字时,不计算平方根(至少在可行的等待时间)! 这种行为有什么有趣的解释吗?!

5 个答案:

答案 0 :(得分:4)

将do-while更改为:

do {
    x = (x+n/x)/2;
    System.out.println(x);
    System.out.println(x*x);
} while(Math.abs(x*x-n)>TOL*2*x);

这重复(输入30.2):

5.495452665613634
30.199999999999992

正如您所看到的那样是5.495452665613634 30.199999999999992的平方,这导致条件Math.abs(x*x-n)>TOL*2*x始终满满(差异为7.105427357601002E-15。条件为> 5.4954526656136345E-15,其中是真的)

换句话说,你忘记了计算机程序存储值有一些限制,或者你的TOL不够高

答案 1 :(得分:2)

整个代码的构建基于这样的前提:在某些时候,您将获得x的正确值。从Random对象获得的内容将影响时间以及您选择的数字大小。

这不是计算sqrt的有效方法。

答案 2 :(得分:0)

为什么随机?一个明智的编码双重选择避免像x*x

这样的计算


在您的代码中,您可以将*2添加到TOL定义并从循环中删除*2

良好的编程删除所有不必要的东西

答案 3 :(得分:0)

“问题”是double具有有限的精度:表示的数字越大,不准确度越大 - 存储不同double的最小变化越大。< / p>

一旦您尝试的答案超过某个数字大小,double无法很好地解析数字,以达到TOL定义的准确度。

答案 4 :(得分:0)

你所拥有的是用于计算数字平方根的所谓Babylonian method。但是,我认为您的停止条件应该只是一个标量(例如TOL)而不是TOL*2*x