题目:任意长度数串,不使用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. Redis EXISTS命令耗时过长case排查

    一.背景 redis慢日志分析平台上线后,随便看了一下,发现onestore使用的缓存集群,存在大量的EXISTS命令慢查询的情况: 平均每个EXISTS命令需要13ms,最大耗时近20ms.这个结果 ...

  2. 简单介绍几种Java后台开发常用框架组合

    01 前言 Java框架一直以来都是面试必备的知识点,而掌握Java框架,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能对当前正在开发中的系统有整体的认知,从而更好的熟悉和学习技术,这篇 ...

  3. Android前沿技术

    一.热升级Tinker源码解析与手写二.热修复阿里百川Sophix内核原理三.App Instantgoogle8.0 类似热更新技术原理与实战四.强制更新1.银行应用非对称加密对称加密五.组件化框架 ...

  4. http-get调用接口简单代码

    一.简单便捷的httpget调用接口,并且返回接口数据1.导入相应的jar包: 2.代码如下: HttpGet get=null; try {HttpClient httpClient = new D ...

  5. 授权公钥登录,sudo权限脚本

    #!/bin/bash############################################################### File Name: key_auth.sh# V ...

  6. Oracle Awr报告_awr报告解读_基础简要信息

    导出 关于awr报告的导出,上一篇博客已经进行过讲述了.博客链接地址:https://www.cnblogs.com/liyasong/p/oracle_report1.html  这里就不再赘述. ...

  7. 微服务-springcloud-注册中心

    创建服务注册中心(eureka-server) 1.创建项目,选择 Eureka Server 别的都不要选择,next-finish 2.application.yml中写入如下信息:通过eurek ...

  8. SpringCloud系列——限流、熔断、降级

    前言 分布式环境下,服务直接相互调用,一个复杂的业务可能要调用多个服务,例如A -> B -> C -> D,当某个服务出现异常(调用超时.调用失败等)将导致整个流程阻塞崩溃,严重的 ...

  9. map的实现--红黑树

    一.什么是红黑树???   红黑树首先是一棵搜索二叉树,树中的每一个结点的颜色不是黑色就是红色.它的特性如下:   1.根节点是黑色   2.每一个结点不是黑色就是红色   3.不能有连续的两个红色结 ...

  10. 从零开始基于go-thrift创建一个RPC服务

    Thrift 是一种被广泛使用的 rpc 框架,可以比较灵活的定义数据结构和函数输入输出参数,并且可以跨语言调用.为了保证服务接口的统一性和可维护性,我们需要在最开始就制定一系列规范并严格遵守,降低后 ...