手动开平方数(结果为整数)-2022

看了很多篇开平方的文章,大多是复制粘贴的,而且也没有讲得清楚明白,这篇倒是给我讲明白了:
手动开平方和立方https://blog.csdn.net/skeeee/article/details/38174017
不过上面这篇文章没有代码,然后我看了这篇有代码的文章
单片机快速开平方的算法
https://blog.csdn.net/liming10cm/article/details/105213756

然后我想啊,如果只是求8位数字的开平方,并不需要循环那么多次,因此我写了下求8位数字的开平方。
举个文字例子:
求169的开平方数
0.这169的二进制数字为1010 1001,从左到右数为第8位到第1位
1.从个位数向左每两位分成一段。
2.最高2位为2,取平方数不大于3的数,即1
3. 2 - 11 = 1,余1(开平方数第4位为1),余数与第6位和第5位数字组成二进制110,即十进制6。
4. 1
4 = 4,试商 6/4 = 1
5,6 / (14+1) = 1,余1(开平方数第3位为1),余数与第4位和第3位组成110,即十进制6。
6. 开平方数的第4位与第3位组成二进制11,即十进制3,试商 6/ 12= 0,那么开平方数第2位为0。
7, 余数110与第2位和第1位组成11001,即十进制25,开平方数前3位组成110,即十进制6,6
4=24,试商25/24=1
8,25/(6*4+1)=1,所以最后一位为1
那么169(10101001)的开平方数为1101,即十进制13
代码如下:

#include <iostream>
#include <string>
using namespace std;
// 求8位的数字的开平方数(开平方数是整数)
unsigned int sqrt8(unsigned int M)
{
	unsigned int N = 0, i;
	unsigned int tmp, ttp;   // 结果、循环计数  

	if ((M == 0) || (M == 1))               // 被开方数,开方结果也为0  
		return M;
	tmp = (M >> 6);          // 获取最高位:B[m-1]  
	N = 0;
	if (tmp >= 1)              // 最高位为1  
	{
		N++;                 // 开平方数的最高位为1  
		tmp = tmp - 1;		// 二进制数,不是0就是1,如果高2位值大于等于1,需要减1后进入循环计算
	}
	// 减数和被减数的区分是:减号前面的数是被减数,减号后面的数是减数。m-s=r,其中m是被减数,s是减数,r是差。
	for (i = 3; i > 0; i--)      // 余下的6位数字可以分成3组,每次移动2位  
	{
		M = (M << 2);			 // 移除高2位
		tmp = (tmp << 2);
		tmp += ((M >> 6) & 0x03);     // 需要过滤高位,只取低两位与tmp相加,得到被减数
		ttp = N;
		ttp = (ttp << 2) + 1; // 减数
		N <<= 1;              // 开平方因数左移一位  
		if (tmp >= ttp)       // 假设成立  
		{
			tmp -= ttp;		// 得到差值进入下一循环
			N++;
		}
	}
	return N;
}
int main() {
	int i;
	for (i = 1; i < 255; i++)
	{
		cout << "i=" << i << endl;
		cout << "calculate=" << sqrt8(i) << endl;
	}
	return 0;
}

求N位数字的开平方数(整数)

#include <iostream>
#include <string>
using namespace std;

unsigned int sqrtN(unsigned long M)
{
	unsigned int N=0,Nbit=0,Nbit1,Nbit2, i;
	unsigned int tmp,temp, ttp;   // 结果、循环计数  
	temp = M;
	if (M == 0)               // 被开方数,开方结果也为0  
		return 0;
	else if (M <= 3)
		return 1;
	if (M > 268435455)
		Nbit1 = 30;
	else if (M > 16777215)
		Nbit1 = 26;
	else if (M > 1048575)
		Nbit1 = 22;
	else if (M > 65535)
		Nbit1 = 18;
	else if (M > 4095)
		Nbit1 = 14;
	else if (M > 255)
		Nbit1 = 10;
	else if (M > 15)
		Nbit1 = 6;
	else if (M <= 15)
		Nbit1 = 2;
	Nbit2 = Nbit1 / 2 ;
	tmp = (M >> Nbit1);          // 获取最高位:B[m-1]  
	N = 0;
	if (tmp >= 1)              // 最高位为1  
	{
		N++;                 // 结果当前位为1,否则为默认的0  
		tmp = tmp-1;
	}

	for (i = Nbit2; i > 0; i--)      // 求剩余的15位  
	{
		M = (M<<2);
		tmp = (tmp << 2) ;
		tmp += ((M >> Nbit1)&0x03);     // 假设  
		ttp = N;
		ttp = (ttp << 2) +1;
		N <<= 1;              // 左移一位  
		if (tmp >= ttp)       // 假设成立  
		{
			tmp -= ttp;
			N++;
		}
	}
	return N;
}
int main() {
	long i;
	for (i = 1; i <= 4096; i++)
	{
		cout << "i=" << i << endl;
		cout << "output=" << sqrtN(i) << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值