不使用已有函数求出1个数的平方根
不使用已有函数求出一个数的平方根
看了牛顿迭代法,还没想清楚为什么。
前一段时间领导出了一道算法题(找出一个数的平方根,精确到小数点后两位,不使用函数库),对此一直耿耿于怀,始终觉得自己的答案是有问题的,但是暂时没有想到其他好的办法。
我是先求出最接近这个数的一个能够整除的平方根,比如说1的平方根是1,2的最接近的平方根也是1,3的最接*方根也是1,而5的最接近的平方跟是2,那么以2为基数,每次叠加0.01,加入说root是平方根,那么找出root 乘以root,然后乘积比该数大0.001的数。具体算法见以下代码:
import java.math.BigDecimal; import java.math.RoundingMode; /** * 找出一个数的平方根,精确到小数点后两位,不使用函数库. * * @author qinge * */ public class Square { public static void main(String[] args) { for (int num = 1; num <= 1000; num++) { System.out.print(num + "的函数平方根:" + Math.sqrt(num)); double root = findSmallRoot(num); System.out.print(" 小数点前一位是:" + root); while (true) { double product = root * root; if (product == num) { System.out.print(" 计算得出平方根是:" + root + "\n"); break; } else if (product > num) {// 此处算法有遗漏 if (product - num > 0.001) { System.out.print(" 计算得出平方根是:" + root + "\n"); break; } } // 用加0.01进行控制 root = root + 0.01; // 对double类型进行精度控制 root = BigDecimal.valueOf(root).setScale(2, RoundingMode.HALF_UP).doubleValue(); } } } /** * 找出num的平方根的小数点前面的数字 * * @param num * @return */ public static int findSmallRoot(int num) { // 遍历平方根的基数,基数的乘机必然会小于等于num for (int i = 1; i <= num && i * i <= num; i++) { // 找出基数则返回 if (i * i == num) { return i; } } // 找num-1 return findSmallRoot(num - 1); } }
相信一些大牛们一定有自己更神奇的算法,那么就贴出来吧!学习膜拜中...
1 楼
thihy
14 小时前
1. 二分!
2. 级数展开!
3. 迭代的方法:如牛顿下山法:http://blog.csdn.net/free4294/article/details/6929950
2. 级数展开!
3. 迭代的方法:如牛顿下山法:http://blog.csdn.net/free4294/article/details/6929950
2 楼
qing_gee
2 小时前
thihy 写道
1. 二分!
2. 级数展开!
3. 迭代的方法:如牛顿下山法:http://blog.csdn.net/free4294/article/details/6929950
2. 级数展开!
3. 迭代的方法:如牛顿下山法:http://blog.csdn.net/free4294/article/details/6929950
看了牛顿迭代法,还没想清楚为什么。
3 楼
lasaka
1 小时前
package acer; import java.io.IOException; import java.util.Scanner; public class Test { public static void main(String aa[]) throws IOException { double inputNumber = 0; int sqare = 0; double sqresult = 0; double closeNumber = 0; double closeNumberMinusOne = 0; double lastCloseNumber = 0; boolean check = true; boolean first = true; Scanner scanner = new Scanner(System.in); inputNumber = scanner.nextDouble();//數字 sqare = scanner.nextInt();//平方數 for (int i = 1; i < inputNumber + 1; i++) { sqresult = i; for (int j = 1; j < sqare; j++) { sqresult *= i; } if (sqresult >= inputNumber) { closeNumber = i; closeNumberMinusOne = closeNumber - 1.0; break; } } while (check) { if (sqresult == inputNumber) { check = false; sqresult = sqare(sqare, closeNumber); } else { // 表示超過小數點第16位了 if (closeNumberMinusOne != 0 && lastCloseNumber == closeNumberMinusOne) { check = false; } if (first) { first = false; lastCloseNumber = closeNumberMinusOne; closeNumberMinusOne += (closeNumber - closeNumberMinusOne) / 2; } else { closeNumber = closeNumberMinusOne; if (sqresult > inputNumber) { if (lastCloseNumber > closeNumberMinusOne) { closeNumberMinusOne -= (lastCloseNumber - closeNumberMinusOne) / 2; } else { closeNumberMinusOne -= (closeNumberMinusOne - lastCloseNumber) / 2; } } else { if (lastCloseNumber > closeNumberMinusOne) { closeNumberMinusOne += (lastCloseNumber - closeNumberMinusOne) / 2; } else { closeNumberMinusOne += (closeNumberMinusOne - lastCloseNumber) / 2; } } lastCloseNumber = closeNumber; } sqresult = sqare(sqare, closeNumberMinusOne); } } } public static double sqare(int sqare, double result) { double sqresult = result; for (int j = 1; j < sqare; j++) { sqresult *= result; } System.err.println("次方根: " + result); System.err.println("次方結果: " + sqresult); return sqresult; } }