简体   繁体   English

使用近似方法实现sqrt方法。 即使条件为假,也无法退出循环

[英]Implement sqrt method using the approximation approach. Cannot exit loop even the condition is false

I am so close to complete my practical question, just stuck at don't know why I cannot exit the loop after getting correct result. 我是如此接近完成我的实际问题,只是坚持不知道为什么我得到正确的结果后无法退出循环。

The question ask to implement sqrt method using the approximation approach. 问题要求使用近似方法实现sqrt方法。

  1. Let num is the number to apply sqrt method. num是应用sqrt方法的数字。
  2. For the num> 1 , lowerLimit = 1 and upperLimit = number 对于num> 1lowerLimit = 1lowerLimit = 1 upperLimit = number
  3. Then find the midpoint of lowerLimit and upperLimit which is (lowerLimit+upperLimit)/2 然后找到midpointlowerLimitupperLimit其是(lowerLimit+upperLimit)/2
  4. Square the midpoint , squareMidpoint = Math.pow(midpoint, 2) 平方midpointsquareMidpoint = Math.pow(midpoint, 2)
  5. If the squareMidpoint > num , upperLimit = midpoint , else lowerLimit= midpoint . 如果squareMidpoint > numsquareMidpoint > num upperLimit = midpoint ,则lowerLimit= midpoint
  6. Repeat third step again until get num with 8 significant digits. 再次重复第三步,直到获得8位有效数字的num。

From step 1 to step 5, I think I did correctly since the output is correct. 从第1步到第5步,我认为我输入正确是正确的。

I actually don't understand step 6 well. 我实际上不太了解第6步。

My problem is if the num = 4 , the program keep printing 2 forever. 我的问题是如果num = 4 ,程序会永远打印2

Here is my code: 这是我的代码:

import java.lang.Math; 
public class p2q4 {

    public static void main(String[] args) {

        //Implement the sqrt method using the approximation approach

        //initialized lowerLimit and upperLimit
        double lowerLimit = 0, upperLimit = 0;

        //num is the number to square root.
        double num = 5;

        //For number greater than one,
        if (num > 1) {
            lowerLimit = 1; //lower limit to one
            upperLimit = num; //upper limit to the number
        }

        double squareMidpoint;
        double midpoint;

        do {
            //Determine the midpoint between the lower and upper limits
            midpoint = (lowerLimit + upperLimit) / 2;

            //Evaluate the square of the midpoint
            squareMidpoint = Math.pow(midpoint, 2);

            //If the square of the midpoint is greater than the number
            if (squareMidpoint > num) {
                //upper limit to the midpoint
                upperLimit = midpoint;
            } else {
                //lower limit to the midpoint
                lowerLimit = midpoint;
            }

            //for debugging purpose
            System.out.printf("midpoint=%f  squareMidpoint=%f upperLimit=%f lowerLimit=%f upperLimit/lowerLimit=%f\n", midpoint, squareMidpoint, upperLimit, lowerLimit, upperLimit/lowerLimit);


        //even though upperLimit/lowerLimit is '1' but still keep looping
        } while (upperLimit/lowerLimit != 1); //I not sure this condition is correct.

        //Output
        System.out.printf("x = %.0f, root = %f\n", num, midpoint);
    }
}

Here is my practical question: 这是我的实际问题:

Instead of using the sqrt method in the Math class, you have been asked to implement the sqrt method using the approximation approach described below: 您已经要求使用下面描述的近似方法实现sqrt方法,而不是在Math类中使用sqrt方法:

For numbers greater than one, the square root method must initially set a lower limit to one and an upper limit to the number (since the square root of the number always lies between one and the number). 对于大于1的数字,平方根方法必须首先将下限设置为1和数字的上限(因为数字的平方根始终位于1和数字之间)。

It must then determine the midpoint between the lower and upper limits and evaluate the square of the midpoint. 然后必须确定下限和上限之间的中点并评估中点的平方。 If the square of the midpoint is greater than the number, the square root method must move the upper limit to the midpoint and similarly if the square of the midpoint is less than the number, it must move the lower limit to the midpoint. 如果中点的平方大于数字,则平方根方法必须将上限移动到中点,类似地,如果中点的平方小于数字,则必须将下限移动到中点。

After moving the appropriate limit, the square root method must evaluate a new midpoint and repeat the process until the desired precision is obtained. 移动适当的限制后,平方根方法必须评估新的中点并重复该过程,直到获得所需的精度。

The required precision for double precision floating point numbers is 8 significant digits. 双精度浮点数所需的精度为8位有效数字。 The precision at any iteration can be determined by dividing the difference between the limits by the lower limit. 任何迭代的精度可以通过将限制之间的差除以下限来确定。

When this is less than 1/108 any number between the limits will be an estimate of the square root of the number to the required precision. 当这小于1/108时,限制之间的任何数字都将是对所需精度的数字的平方根的估计。 To minimize the error, the square root method should return the midpoint between the final limits that satisfy the precision requirement. 为了最小化误差,平方根方法应返回满足精度要求的最终限制之间的中点。

The square root method must return exact values for the special cases of zero and one. 平方根方法必须返回零和一的特殊情况的精确值。

If an application attempts to calculate the square root of a negative number, the square root method should display an appropriate message and terminate the program. 如果应用程序尝试计算负数的平方根,则平方根方法应显示相应的消息并终止该程序。

Any help is appreciated! 任何帮助表示赞赏!

If you print upperLimit/lowerLimit with more significant digits, you'll see that it gets as small as 1.0000000000000002 , but never reaches 1, which is why your loop never ends. 如果使用更高位数打印upperLimit/lowerLimit ,您将看到它小到1.0000000000000002 ,但永远不会达到1,这就是您的循环永远不会结束的原因。

Instead of staying in the loop as long as: 只要:不要停留在循环中:

upperLimit/lowerLimit != 1

you should change the condition to: 你应该把条件改为:

while (upperLimit - lowerLimit > 0.0000000001)

which will exit the loop when the limits get close enough to each other. 当限制彼此足够接近时,它将退出循环。

That's what step #6 means by "8 significant digits" - your approximation should get the first 8 significant digits correct. 这就是步骤#6的意思是“8位有效数字” - 你的近似应该得到前8位有效数字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM