题目:任意长度数串,不使用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. 用java打印日历

    来自<java核心技术卷一> /** * Created by wangbin10 on 2019/1/3. * 打印当月日历 */ public class CalendarTest { ...

  2. python常用删除库的方法

    本文记于初学py的时候,两年后补发. python常用库的安装方法一般有几种,比如: 1.编译过的exe包,直接无脑下一步就可以了. 2.pip install 库名,快速安装.自动匹配最新版本. 3 ...

  3. 高中生也能读懂的Docker入门教程

    Docker 是 Golang 编写的, 自 2013 年推出以来,受到越来越多的开发者的关注.如果你关注最新的技术发展,那么你一定听说过 Docker.不管是云服务还是微服务(Microservic ...

  4. 系统学习 Java IO (五)----使用 SequenceInputStream 组合多个流

    目录:系统学习 Java IO---- 目录,概览 SequenceInputStream 可以将两个或多个其他 InputStream 合并为一个. 首先,SequenceInputStream 将 ...

  5. laravel扩展包-私有库

    创建一个新的laravel项目 composer create-project --prefer-dist laravel/laravel laravel-package "5.5.*&qu ...

  6. apache出现forbidden

    <Directory /> Options FollowSymLinks AllowOverride All Order deny,allow allow from all Require ...

  7. Solr配置文件 schema.xml

    1 添加自己的分词器(mmseg4j) 意思是textCommplex 这个类型,用的是 com.chenlb.mmseg4j.solr.MMSegTokenizerFactory 这个分词器,词库是 ...

  8. 自己实现AOP,AOP实现的步骤分解

    自己实现简易的AOP 一.需求:自己实现AOP:1.0版本:在某个方法上加"@InOutLog"注解,那么执行到该方法时,方法的前面.后面会输出日志信息. [自己实现AOP 2.0 ...

  9. python3.7 AES.MODE_ECB(128位) pkcs5padding 加密算法

    用惯用的写法总报TypeEerror错误,经过调试,总算成功啦,直接上代码 TypeError("Object type %s cannot be passed to C code" ...

  10. scrapy 发post请求

    可以使用 yield scrapy.FormRequest(url, formdata, callback)方法发送POST请求. 如果希望程序执行一开始就发送POST请求,可以重写Spider类的s ...