如何使用java语言计算一个正整数的平方根呢(自定义Sqrt函数)?

今天的这篇文章是我在刷算法题的时候遇到的,最简单的方法是直接调用java里面的Sqrt函数,不过有时候题目中会要求我们不能使用库函数,所以在这里我们自己定义Sqrt方法。

最常见的思路有两种,第一种是二分法,第二种是牛顿的微积分思想。没错,想当年大学时候学了很久很痛苦的微积分,被我第一次派上用场了。对于这两种方法我们一个一个看。

一、二分法

二分法的思想很简单,就是从0到N不断的去缩小范围来找一个一个满足精度的最佳值。我们举一个函数的例子:
在这里插入图片描述
这就是二分法的思想,求平方根也是,我们从0到value取出中间值,然后不断地比较,假设value=10,查找区间为(0,10),这时候取(0,10)的中间值mid=5,mid*mid再和value比较之后,确定下一次查找的区间变为(0,5),依次类推。一直到满足我们需要的精度即可。下面我们使用java代码实现一下:

	static double MySqrt(int value, double t){
		if (value < 0 || t<0)
			return 0;
		double left = 0;
		double right = value;
		double mid = (right + left) / 2;
		double offset = 2*t ;
		while (offset>t){
			double temp = mid*mid;
			if (temp > value){
				right = (left + right) / 2;
				offset = temp - value;
			}
			if (temp <= value){
				left = (left + right) / 2;
				offset = value - temp;
			}
			mid = (left + right) / 2;
		}
		return mid;
	}

在这里value就是我们要求的数字,t表示的是精度。这个方法在这,大家可以测试一遍。不过在这里有一个小小的问题需要我们去注意:

如果我们对整数9取平方根,结果不是3,这里有精度损失,损失的原因之一是和计算机有关的,因为计算机的底层其实只有0和1,所以会无限的接近,而不能精确表示。

以上就是二分法求解的思想,这个思想很简单,不过实现的方法却是有一点点麻烦。在这里我们开始介绍第二种方法,那就是牛顿的微积分思想

二、牛顿迭代法

牛顿的微积分的思想就是无限接近,在这里提一句,如果你是数学大佬就不要追究思想到底是啥了。对于求平方根来说,使用切线来无限逼近的方式有时候能起到意想不到的效果。

设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,

L的方程为y = f(x0)+f’(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f’(x0),称x1为r的一次近似值。

过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标 x2 = x1-f(x1)/f’(x1),称x2为r的二次近似值。

重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f’(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式。

我们使用一张图来演示一下:

在这里插入图片描述
这种方式也很好理解。所以我们直接来看实现:

static double SqrtIterator(int value,double t){
	double temp = value;
	while (fabs(temp*temp-value)>t){
		temp=(temp+value/temp) / 2.0;
	}
	return temp;
}
//取绝对值
private static double fabs(double a) {
	return (a < 0) ? -a : a;
}

上面的方法同样可以表示。而且我们可以看到,牛顿的这个方法其实更加的简单。而且精度也更好。
在这里插入图片描述

<think>我们已知用户想要计算正整数平方根并向上取整。在Python中,我们可以分两步: 1. 计算平方根使用math.sqrt或指数运算) 2. 对结果向上取整(使用math.ceil) 注意:由于平方根可能是整数(如4的平方根为2)也可能是小数(如5的平方根约为2.236),向上取整就是取比这个数大的最小整数(对于5的平方根,向上取整为3)。 但是,这里有一个特殊情况:如果平方根本身就是整数,那么向上取整就是它本身(如4的平方根是2.0,向上取整还是2)。所以,我们可以使用math.ceil函数。 步骤: 1. 导入math模块 2. 计算平方根 3. 对平方根结果向上取整 示例代码: import math n = 5 root = math.sqrt(n) # 计算平方根,得到2.236... ceil_root = math.ceil(root) # 向上取整,得到3 另外,我们也可以使用整数运算的方法,比如利用整数平方根(isqrt)然后判断。但是,注意math.isqrt是向下取整的整数平方根。例如,math.isqrt(5)返回2。如果我们想要向上取整,可以这样: 如果平方根的整数部分平方等于原数,则向上取整就是整数部分,否则是整数部分+1。 但是,使用math.ceil(math.sqrt(n))是最直接的方法。 注意:math.ceil返回的是整数,但类型是float(因为math.sqrt返回的是float)。如果我们想要整数,可以转换为int。 然而,对于大整数,浮点数运算可能会有精度问题,导致平方根计算不准确。因此,对于大整数,建议使用整数运算的方法。 两种方法对比: 方法1(浮点数):适用于一般情况,但大整数可能有精度问题。 方法2(整数运算):使用math.isqrt(Python3.8+)然后判断,更安全。 方法2的代码: import math n = 5 isqrt_val = math.isqrt(n) # 整数平方根(向下取整) if isqrt_val * isqrt_val == n: ceil_root = isqrt_val else: ceil_root = isqrt_val + 1 这样,ceil_root就是向上取整的结果。 因此,我们提供两种方法,并说明适用情况。 根据用户的问题,他要求的是向上取整,所以我们可以根据情况选择。 考虑到用户输入的是正整数,且可能很大,我们更推荐使用整数运算的方法(方法2)以避免精度问题。 但注意:方法2只适用于非负整数,而用户要求的是正整数,所以符合。 所以,我们可以这样写: 方法一(浮点数方法): import math ceil_root = math.ceil(math.sqrt(n)) 方法二(整数方法,避免浮点精度问题): import math isqrt_val = math.isqrt(n) if isqrt_val * isqrt_val == n: ceil_root = isqrt_val else: ceil_root = isqrt_val + 1 我们推荐方法二,因为更精确。 另外,如果用户使用的是Python3.8以下的版本,则没有math.isqrt,那么可以使用整数平方根的近似计算方法(比如牛顿法)或者使用浮点数方法(但要小心大整数)。 下面,我们给出完整的代码示例,包括用户输入和两种方法。 同时,我们生成相关问题。</think>在 Python 中计算正整数平方根并进行向上取整,可以使用以下两种方法: ### 方法一:使用 `math` 模块(推荐) ```python import math def ceil_sqrt(n): """ 计算正整数n的平方根并向上取整 参数: n -- 正整数 返回: 平方根的向上取整值 """ sqrt_val = math.sqrt(n) # 计算平方根 return math.ceil(sqrt_val) # 向上取整 # 示例 print(ceil_sqrt(10)) # 输出:4 (因为√10≈3.162,向上取整为4) print(ceil_sqrt(16)) # 输出:4 (因为√16=4.0,向上取整仍为4) ``` ### 方法二:使用整数运算(避免浮点精度问题) ```python import math def ceil_sqrt(n): """ 计算正整数n的平方根并向上取整(整数方法) 参数: n -- 正整数 返回: 平方根的向上取整值 """ isqrt_val = math.isqrt(n) # 整数平方根(向下取整) if isqrt_val * isqrt_val == n: return isqrt_val # 完全平方数直接返回 else: return isqrt_val + 1 # 非完全平方数加1 # 示例 print(ceil_sqrt(15)) # 输出:4 (因为√15≈3.87,向上取整为4) print(ceil_sqrt(25)) # 输出:5 (因为√25=5.0) ``` ### 关键说明: 1. **`math.ceil()` 函数**:将浮点数向上取整到最接近的整数 - 例如:`math.ceil(3.1) = 4`, `math.ceil(4.0) = 4` 2. **`math.isqrt()` 函数**(Python 3.8+): - 返回整数平方根(向下取整) - 比 `math.floor(math.sqrt())` 更精确高效,避免浮点精度问题[^1] 3. **完全平方数处理**: - 当 $n$ 是完全平方数时(如 16, 25),平方根本身就是整数 - 非完全平方数(如 10, 15)需要向上取整 4. **大整数处理**: - 对于非常大的整数(如 $10^{100}$),推荐使用整数方法避免浮点精度丢失 ### 完整示例(含用户输入): ```python import math def main(): try: n = int(input("请输入一个正整数:")) if n <= 0: raise ValueError("必须是正整数") # 方法1:浮点数方法 float_method = math.ceil(math.sqrt(n)) # 方法2:整数方法(推荐) isqrt_val = math.isqrt(n) int_method = isqrt_val if isqrt_val**2 == n else isqrt_val + 1 print(f"浮点数方法: √{n} ≈ {math.sqrt(n):.4f} → 向上取整 = {float_method}") print(f"整数方法: √{n} 的向上取整 = {int_method}") except ValueError as e: print(f"输入错误: {e}") if __name__ == "__main__": main() ``` ### 相关问题: 1. 如何计算负数的平方根并向上取整? (需使用复数运算,结果可能是虚数) 2. Python 中向下取整平方根有哪些方法? (使用 `math.floor(math.sqrt())` 或 `math.isqrt()`) 3. 如何判断一个数是否为完全平方数? (检查 `math.isqrt(n)**2 == n`) 4. 大整数的平方根计算如何避免精度问题? (推荐使用 `math.isqrt()` 或 `decimal` 模块) 5. Python 中如何进行其他数学取整操作? (四舍五入 `round()`,向下取整 `math.floor()`)[^3] [^1]: Python 提供了多种计算平方根函数和运算符。 [^2]: 可通过用户输入实现交互式计算程序。 [^3]: 数学取整操作在科学计算中很常见。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值