【问题标题】:Calculating Square Root to 50 places计算平方根到 50 位
【发布时间】:2013-10-14 19:33:40
【问题描述】:

我正在做一个科学展览项目,测试五种不同的平方根算法来计算两个的平方根。 (见我的问题here)。

我有两个选择。

  • 将每个程序运行一段时间,然后比较最终结果与 2 的平方根的接近程度。
  • 运行每个程序,直到 2 的平方根精确到小数点后 50 位,然后使用 System.nanoTime() 比较所用时间

第二个的缺点是每次迭代检查它是否准确到小数点后五十位的过程需要一些时间,因此结果不会准确。如果有其他方法可以做到这一点,请告诉我

第一个的缺点是我不知道如何在设定的时间内运行程序。

我应该采取什么行动?

【问题讨论】:

  • 请向我们展示您迄今为止所做的努力 - 您尝试解决问题的方法。
  • (侧身想)计算你的根一次,然后检查它的数字一千次。将该时间除以 1,000,您就知道检查费用是多少。 (关于-ish。当心缓存问题——您确实不想希望将其中任何一个的单次运行与彼此进行比较。)

标签: java square-root


【解决方案1】:

我不知道如何在一定时间内运行程序。

一种选择是在一个线程中运行需要运行 x 次的代码。
时间到时终止线程,然后让线程代码显示其结果。
像这样的东西。

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

然后你使用伪代码启动线程:

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.

你实际上如何做很短的睡眠是任务的一部分,所以我会把它留给你去发现。

【讨论】:

    【解决方案2】:

    每种方法的测试所用时间是相同的。因此,如果您对比较感兴趣,这不是缺点。另外,我怀疑测试所花费的时间并不重要。

    另外:无论如何你都需要这样的测试。通常人们对直到给定错误的结果感兴趣。由于所需时间取决于许多其他因素(CPU、JVM 等),因此在已知时间内无法获得未知的准确性。由此投票支持第二种方法。

    【讨论】:

      【解决方案3】:

      如果你做了一定的时间,然后中断这个过程,你有一个有趣的问题要回答:

      • 您是否收集了足够的数据来回答问题?

      我会让你思考这个问题,同时我会建议你如何打断仍在计算中的答案。

      首先,您应该提前知道平方根的前 50 位数字,因为您需要这些数字才能“知道”答案是否正确。正确性应该与需要多长时间无关,所以也许您只需验证一次计算,然后硬编码正确的答案。

      其次,您需要将平方根计算算法打包到可以运行的东西中。我建议使用 Java 接口 Runnable,它强制使用带有签名的方法

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

      然后您将拥有可以与 Java Thread 很好地融合的东西,并且您可以中断 Java 线程。一旦中断了线程的结果,就不能信任线程内部的任何计算(正常情况下)。

      最简单的方法(因为你的项目不是利用最新的 Java 技术,而是试图反驳你的反假设)是做类似的事情

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

      稍后如果您发现某些事情花费的时间太长

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

      请注意,这是一种非常不雅的方式来停止线程,并且您不能信任 Runnable1 之后所做的任何事情。

      还有其他更复杂的技术可用,例如:

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

      上面的例子有很多特性确实可以提高 Java 代码的质量;但是,请注意,代码的质量与证明您的观点无关。有可能把代码打磨得很好,忘记真正解决问题。

      上面的代码会被调用

      Runnable1 runnable1 = new Runnable1();
      Thread thread1 = new Thread(runnable1);
      thread1.start
      
      // some means of waiting
      Thread.sleep(10000); // sleeps 10 seconds
      runnable1.shutdown();
      

      此技术会在已知状态下(在下一次循环迭代之前)关闭您的可运行文件,因此您可能随后可以从该技术中捕获一些中间数据,前提是 Runnable 的其余部分可以报告中间解决方案。

      【讨论】:

      • 首先,我会避免扩展 Thread 类,就好像您决定使用 Java 的一些更好的并发特性一样,无论如何您都必须“取消编写”该代码。跨度>
      猜你喜欢
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      相关资源
      最近更新 更多