看了很多篇开平方的文章,大多是复制粘贴的,而且也没有讲得清楚明白,这篇倒是给我讲明白了:
手动开平方和立方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. 14 = 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,64=24,试商25/24=1
8,25/(6*4+1)=1,所以最后一位为1
那么169(10101001)的开平方数为1101,即十进制13
代码如下:
#include
#include
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
#include
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;
}