题目:任意长度数串,不使用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. Laravel --- 自动生成数据

    1.创建填充文件:php artisan make:seeder UserTableSeeder 2.在run方法里面写填充数据的代码: use Illuminate\Database\Seeder; ...

  2. C++虚函数与虚表

    有一定面向对象知识的朋友对继承与多态一定很熟悉,C++想实现继承的话就要使用虚函数,那么什么是虚函数,其原理是什么,下面尽量给大家分析一下C++中其运行机制: 首先,基础,什么是虚函数,什么是多态? ...

  3. Centos7 fstab盘符挂载硬盘导致重启系统失败解决办法

    服务器拥有多个硬盘插槽,在进行维护或重启时,这些硬盘的相对位置可能发生变化.利用盘符(dev/vda)方式挂载磁盘,可能由于磁盘顺序变化导致重启时读取fstab文件发生错误,从而无法正常重启服务器. ...

  4. 惊:FastThreadLocal吞吐量居然是ThreadLocal的3倍!!!

    说明 接着上次手撕面试题ThreadLocal!!!面试官一听,哎呦不错哦!本文将继续上文的话题,来聊聊FastThreadLocal,目前关于FastThreadLocal的很多文章都有点老有点过时 ...

  5. vue回顶部 组件 可以直接使用

    <template> <div id="goTop"> <div class="goTop" v-show="goTop ...

  6. @Autowired自动注入失败

    新手注意的问题 package cn.ryq.web.controller; import cn.ryq.domain.company.Company;import cn.ryq.service.co ...

  7. 【Go】使用压缩文件优化io (二)

    原文链接: https://blog.thinkeridea.com/201907/go/compress_file_io_optimization2.html 上一篇文章<使用压缩文件优化io ...

  8. Python 爬虫从入门到进阶之路(十五)

    之前的文章我们介绍了一下 Python 的 json 模块,本章我们就介绍一下之前根据 Xpath 模块做的爬取<糗事百科>的糗事进行丰富和完善. 在 Xpath 模块的爬取糗百的案例中我 ...

  9. python网络爬虫(11)近期电影票房或热度信息爬取

    目标意义 为了理解动态网站中一些数据如何获取,做一个简单的分析. 说明 思路,原始代码来源于:https://book.douban.com/subject/27061630/. 构造-下载器 构造分 ...

  10. 数字IC后端布局阶段对Tie-high和Tie-low Net的处理

    本文转自:自己的微信公众号<集成电路设计及EDA教程> 里面主要讲解数字IC前端.后端.DFT.低功耗设计以及验证等相关知识,并且讲解了其中用到的各种EDA工具的教程. 考虑到微信公众平台 ...