1 package com.company;
2
3
4 import org.junit.Test;
5
6 public class Lesson3_2 {
7
8 /**
9 * @Description: 计算大于1的正整数之平方根
10 * @param n-待求的数, deltaThreshold-误差的阈值, maxTry-二分查找的最大次数
11 * @return double-平方根的解
12 */
13 public static double getSqureRoot(int n, double deltaThreshold, int maxTry) {
14
15 if (n <= 1) {
16 return -1.0;
17 }
18
19 double min = 1.0, max = (double)n;
20 for (int i = 0; i < maxTry; i++) {
21 double middle = (min + max) / 2;
22 double square = middle * middle;
23 double delta = Math.abs((square / n) - 1);
24 if (delta <= deltaThreshold) {
25 return middle;
26 } else {
27 if (square > n) {
28 max = middle;
29 } else {
30 min = middle;
31 }
32 }
33 }
34
35 return -2.0;
36
37 }
38
39 @Test
40 public void Test1()
41 {
42 int number = 10;
43 double squareRoot = Lesson3_2.getSqureRoot(number, 0.000001, 10000);
44 if (squareRoot == -1.0) {
45 System.out.println("请输入大于1的整数");
46 } else if (squareRoot == -2.0) {
47 System.out.println("未能找到解");
48 } else {
49 System.out.println(String.format("%d的平方根是%f", number, squareRoot));
50 }
51 }
52 }
- 原理 二分法基于这样一个事实:对于一个非负实数 \(x\),其平方根一定在区间 \([0, x]\)(当 \(x \geq 1\) 时)或者 \([x, 1]\)(当 \(0 < x < 1\) 时)内。通过不断将这个区间一分为二,然后判断中间值的平方与 \(x\) 的大小关系,逐步缩小包含平方根的区间范围,直到达到所需的精度。
- 步骤
- 确定初始区间 \([a, b]\):若 \(x \geq 1\),令 \(a = 0\),\(b = x\);若 \(0 < x < 1\),令 \(a = x\),\(b = 1\)。
- 计算区间中点 \(mid=(a + b) / 2\)。
- 比较 \(mid^2\) 与 \(x\) 的大小:
- 如果 \(mid^2\) 约等于 \(x\)(在给定的误差范围内),则 \(mid\) 就是所求的近似平方根。
- 如果 \(mid^2 > x\),说明平方根在区间 \([a, mid]\) 内,令 \(b = mid\)。
- 如果 \(mid^2 < x\),说明平方根在区间 \([mid, b]\) 内,令 \(a = mid\)。
- 重复上述步骤,直到满足精度要求。