题目:任意长度数串,不使用sqrt函数,手工计算平方根?
 
要求只准用加/减/乘/除四则运算,不准使用power/sqrt等函数。
 
算法如下:
1、以小数点为中心往两边每2位分隔为一组;
2、然后以组为单位,从左往右扫描计算;
3、先对第一组数,找个N*N最大但不超过第一组数的数N,作为结果R的第1位;
4、然后用第一组数减去N*N的余数,作为下次计算的数首部,将下一组两位往下移构成一个新的待计算数W;
5、将第3步已得结果R乘以20作为除数首部+尾数X,再乘于X,使得结果T最大但不超过待计算数,X作为结果R的第2位;
6、然后用W减去T作为余数,作为下次计算的数首部,将下一组两位往下移构成一个新的待计算数W;
7、然后再将已有结果R乘以20作为除数首部+尾数X,再乘于X,使得结果T最大但不超过待计算数W,X作为结果R的下一位;
8、重复6~7,直至达到你期望的精度位数为止
 
C/C++语言实现算法
(粘贴到这里无格式对齐了,请自行格式化):
//以计算到小数点后32位为例;
//Written by 凌志辉.
//Email:251210269@qq.com
void square_root(char *pszNum)
{
#define IsZero(a) ( fabs(a) < 0.000001f)
#define PRECISIONCNT 32
 
#ifdef WIN32
#define _itoa_ _itoa_s
#define _strcpy_ strcpy_s
#define _sprintf_ sprintf_s
#else
#define _itoa_ itoa
#define _strcpy_ strcpy
#define _sprintf_ sprintf
#endif
 
int i = 0, nPrecisionCnt = 0;
double fLeft = 0.0f, fTail = 0.0f;
double fNum = 0.0f, tmp = 0.0f;
bool bEvenInteger = false; //整数部分偶数位
bool bCalcDecimal = false; //开始计算小数部分
char *pDot = strstr(pszNum, ".");
bool bInteger = (NULL == pDot); //整数吗
char szResult[1024] = {0}; //存结果R
char szCalcNum[1024] = {0}; //被除数W
char szDivision[1024] = {0}; //除数
char szZero[4] = {'0', '0', '0','\0'};
char *p = pszNum;
char *r = szResult;
char *d = szDivision;
char *c = szCalcNum;
 
 
if (NULL == pszNum)
return;
 
 
bEvenInteger = bInteger ? (0 == strlen(pszNum) % 2) : (0 == (pDot - pszNum) % 2);
//1、先计算首部
*c++=*p++;
if (bEvenInteger)
{
*c++=*p++;
}
 
fLeft = 0.0f;
fNum = atof(szCalcNum);
 
//第一组数的计算, 首位范围[0~99]
for ( i = 1; i <= 9; i++)
{
if (i * i > fNum)
{
i--;
fLeft = (fNum - i * i);
_itoa_((int)fLeft, szCalcNum, 10);
c = szCalcNum + strlen(szCalcNum);
break;
}
 
if ( IsZero(i * i - fNum) )
{
fLeft = 0.0f;
c = szCalcNum;
break;
}
}
 
_itoa_(i, szResult, 10);
_strcpy_(szDivision, szResult);
r = szResult + strlen(szResult);
d = szDivision + strlen(szDivision);
 
//2、计算第二组数以及以后,由于int型位数最大只占10位,故全采用double型
while (true)
{
if (0 == *p && IsZero(fLeft))
{ //正好完全平方数
*r = '\0';
break;
}
 
if (0 == *p && !IsZero(fLeft) && !bCalcDecimal)
{ //不是平方数,然后计算更多的小数部分
 
if (bInteger) /*整数计算,补小数点*/
*r++ = '.';
 
bCalcDecimal = true;
}
 
if (bCalcDecimal)
{
nPrecisionCnt++;
p = szZero;
 
if (nPrecisionCnt > PRECISIONCNT)
{
*r = '\0';
break;
}
}
 
//非整数运算,若遇到小数点
if (!bInteger && '.' == *p)
{
*r++ = '.';
p++;
}
 
*c++=*p++; *c++=*p++;
 
tmp = 20 * atof(szDivision);
fNum = atof(szCalcNum);
 
fTail = ceil(fNum / tmp);
 
while ( (tmp + fTail) * fTail > fNum) fTail--;
*r++ = (char)(fTail + 48);
*d++ = (char)(fTail + 48);
 
fLeft =fNum - (tmp + fTail) * fTail;
memset(szCalcNum, 0, 1024);
if ( !IsZero(fLeft) )
{
_sprintf_(szCalcNum, "%.0f", fLeft);
}
c = szCalcNum + strlen(szCalcNum);
}
 
printf ("%s\n", szResult);
 
#undef _itoa_
#undef _strcpy_
#undef _sprintf_
}
 
调用示例:
……
square_root("59");
square_root("72.25");
……

技术派-不用sqrt手工计算平方根的更多相关文章

  1. .NET练习计算平方根

    1.新建Windows窗体 2.窗体中添加控件:TextBox(文本框).Button(按钮).和Label(标签) 3.为Button对象添加点击事件代码 点击事件代码设计思路 ①从文本框中获取输入 ...

  2. Carmack在QUAKE3中使用的计算平方根的函数

    // // Carmack在QUAKE3中使用的计算平方根的函数 // float CarmSqrt(float x){ union{ int intPart; float floatPart; } ...

  3. 蓝桥杯 第三届C/C++预赛真题(9) 夺冠概率(手工计算概率)

    足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能. 假设有甲.乙.丙.丁四个球队.根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表: 甲 乙 丙 丁 甲 - 0.1 0.3 0.5乙 ...

  4. SpreadJS + GcExcel 一出,谁与争锋!全栈表格技术轻松应对复杂公式计算场景(一)

    设计思路篇 Excel是我们日常办公中最常用的电子表格程序,不仅可满足报表数据的计算需求,还可提供绘图.数据透视分析.BI和Visual Basic for Applications (VBA)宏语言 ...

  5. [LeetCode] Sqrt(x) 求平方根

    Implement int sqrt(int x). Compute and return the square root of x. 这道题要求我们求平方根,我们能想到的方法就是算一个候选值的平方, ...

  6. 069 Sqrt(x) 求平方根

    实现 int sqrt(int x) 函数.计算并返回 x 的平方根.x 保证是一个非负整数.案例 1:输入: 4输出: 2案例 2:输入: 8输出: 2说明: 8 的平方根是 2.82842..., ...

  7. [LeetCode] 69. Sqrt(x) 求平方根

    Implement int sqrt(int x). Compute and return the square root of x, where x is guaranteed to be a no ...

  8. LeetCode 69. Sqrt(x) (平方根)

    Implement int sqrt(int x). Compute and return the square root of x. x is guaranteed to be a non-nega ...

  9. 你能不用计算机来计算S=a+(a+1)+(a+2) + ...... + b的解的数目吗?

    S=a + (a + 1) + (a + 2) + ...... + b(其中a, b > 0) 现在我们要求,给定一个正整数S,求有多少种不同的<a,b>,使得上述的等式成立. 这 ...

随机推荐

  1. Linux基础(二)

    网卡的启动与关闭 ipup ens33 启动网卡 ifdown 关闭网卡 普通用户没有该权限 root用户,管理员,普通用户的权限 root 至高无上的 root用户所在的组是root组 ​ 管理员 ...

  2. ZooKeeper学习第八期——ZooKeeper伸缩性(转)

    转载来源:https://www.cnblogs.com/sunddenly/p/4143306.html 一.ZooKeeper中Observer 1.1 ZooKeeper角色 经过前面的介绍,我 ...

  3. export命令的使用

    一:export将环境变量昭告天下     1.直接输入export会将显示bash下的所有环境变量       2.env/set/export/declare都可以显示shell的变量       ...

  4. 设计模式之装饰器模式(decorator pattern)

    装饰器模式主要对现有的类对象进行包裹和封装,以期望在不改变类对象及其类定义的情况下,为对象添加额外功能.是一种对象结构型模式.需要注意的是,该过程是通过调用被包裹之后的对象完成功能添加的,而不是直接修 ...

  5. 自定义实现一个loghub(或kafka)的动态分片消费者负载均衡?

    一般地,像kafka之类的消息中间件,作为一个可以保持历史消息的组件,其消费模型一般是主动拉取方式.这是为了给消费者足够的自由,回滚或者前进. 然而,也正是由于将消费消息的权力交给了消费者,所以,消费 ...

  6. jQuery中ajax-$.getJSON,$.getScript

    jQuery提供了两个特定异步加载的方法$.getJSON()方法和$.getScript()方法 $.getJSON()来加载特定的json文件 $.getScript()来加载特定的javascr ...

  7. Hadoop起步之图解SSH、免密登录原理和实现

    1. 前言 emmm….最近学习大数据,需要搭建Hadoop框架,当弄好linux系统之后,第一件事就是SSH免密登录的设置.对于SSH,我觉得使用过linux系统的程序员应该并不陌生.可是吧,用起来 ...

  8. EditPlus VC2010 and 2008 C/C++配置

    源自:http://blog.csdn.net/weiling_shen/archive/2010/03/26/5421017.aspx 对于2010跟2008差不多,只需相应的修改一下路径即可:如2 ...

  9. Codeforces Gym100543L:Outer space invaders(区间DP)

    题目链接 题意 有n个人,每个人有一个出现时间a和一个开枪时间b和一个距离d,在任意一个时刻,你可以选择炸人,你要炸一个人的花费是和他的距离d,并且所有的已经出现并且还没开枪的和你距离<=d的人 ...

  10. 深入学习Spring框架(二)- 注解配置

    1.为什么要学习Spring的注解配置? 基于注解配置的方式也已经逐渐代替xml.所以我们必须要掌握使用注解的方式配置Spring. 关于实际的开发中到底使用xml还是注解,每家公司有着不同的使用习惯 ...