[从零开始学算法]求平方根

article/2025/9/21 16:28:08

这次我们来学习一下如何求平方根。在计算机中很难有精确的求出数据的平方根的算法,基本都是要求一个误差可接受范围内的近似值。治理我们取误差值为1e-5。
笔者的编程语言及环境如下

  1. 编程语言:c++
  2. 编译器:Code Blocks
  3. 系统: windows 10 x64

    求平方根的方法

      • 二分法
      • 递归法(牛顿法)
      • 卡马克法
      • 完整代码展示

二分法

二分法求平方根的思路如下:

  1. 设置一个初始区间[0,n],若n<1则初始区间为[0,1]。
  2. 取区间中值mid的平方与数据n比较。
  3. 若数据n小则令区间变为[0,mid];否则变为[mid,n(或1)]。
  4. 若先后两次中值的差在误差范围内,则此次mid为平方根的近似值。

代码如下:

double sqrt(double number)//二分法
{double low=0.0,high=number>1?number:1;double mid=0,last=0;do{last=mid;mid=(low+high)/2;if(mid*mid>number)high=mid;else low=mid;}while(fabs(mid-last)>1e-5);return mid;
}

以123456789012为测试数据结果如下
在这里插入图片描述

递归法(牛顿法)

迭代法求平方根的主要思路为:

  1. 令x为任意值(通常取数据n的一半)。
  2. 令y=(x+n/x)/2。
  3. 若x与y的差在误差范围内,则y为平方根近似值;否则令x=y执行第2步

代码如下:

double sqrt1(double number,double x)
{double y=(x+number/x)/2;return fabs(y-x)<0.001?y:sqrt1(number,y);
}

以123456789012测试结果如下:
在这里插入图片描述

卡马克法

可以在上文看到牛顿迭代算法的初值是任意的,一个好的初值可以大大降低迭代次数。卡马克算法所求的是平方根的倒数(在实际应用中平方根的倒数比平方根用的多)。卡马克算法可以理解为优化的迭代算法,其选择了一个极好的初值,将算法优化到一次或两次迭代就可以达到误差范围内。因为其涉及到浮点数在计算机内的存储方式及Magic Number,这里将不再赘述,有兴趣的可以自行百度。
因为其涉及到浮点数的存储,而系统中float与double的存储不一样,所以有float与double两种版本。
float版代码如下:

float sqrt(float x)
{float xhalf = 0.5 * x;xint i = *(int*)&x; // 将x值按计算机中的存储格式强转成int赋值给ii = 0x5f3759df - (i >> 1); //现在float最优魔值是0x5f375a86 所以上面的代码可以用  i = 0x5f375a86 - (i >> 1); 替换x = *(float*)&i; x = x * (1.5 - xhalf * x * x); // 一次牛顿迭代//x = x * (1.5 - xhalf * x * x); // 二次牛顿迭代return x;
}

说实话,笔者对于 int i = (int)&x;这种写法也就见过这么一次,可以说卡马克算法无论是从思想上还是代码上都极具魅力,你能想象到求平方根算法连一个循环一个迭代都没有么!世上没有取巧的代码,只有强大的理论。
同样以123456789012测试,其效果如下:
在这里插入图片描述
我们可以看到数据同一二种方法有了数据差异,但是数据差异仅有0.1%,可以说是完全可以接受。如果迭代两次的话效果如下图:
在这里插入图片描述
误差来到了0.0002%,可太可怕了。
下面附上处理double型数据的代码,就不进行效果展示了:

double sqrt(double number)
{__int64 i;double x2, y;const double threehalfs = 1.5F;x2 = number * 0.5F;y  = number;i  = * ( __int64 * ) &y;i  = 0x5fe6ec85e7de30da - ( i >> 1 );y  = * ( double * ) &i;y  = y * ( threehalfs - ( x2 * y * y ) ); // 一次牛顿迭代//y  = y * ( threehalfs - ( x2 * y * y ) ); // 二次迭代return y;
}

完整代码展示

现在对以上三种方法进行整体代码演示:

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
double sqrt0(double number);//二分法
double sqrt1(double number,double x);//牛顿迭代法
float sqrt2(float x);//卡马克快速平方根
double sqrt3(double number);//double版
int main()
{freopen("in.txt","r",stdin);cout.setf(ios::fixed,ios::floatfield);cout.precision(7);double number,once,twice,others;cin>>number;cout<<"测试数据:"<<number<<endl;cout<<"二分法求平方根:"<<sqrt0(number)<<endl;cout<<"迭代法求平方根: "<<sqrt1(number,number/2)<<endl;others=sqrt0(number);once=1/sqrt3(number);//卡马克法得出的是平方根倒数twice=1/sqrt2(number);//在一定数据范围内float和double相互转化可以不损失精度cout<<"一次迭代卡马克法求平方根: "<<once<<"  相差比"<<fabs(once-others)/others<<endl;cout<<"二次迭代卡马克法求平方根: "<<twice<<"  相差比"<<fabs(twice-others)/others<<endl;return 0;
}
double sqrt0(double number)
{double low=0.0,high=number>1?number:1;double mid=0,last=0;do{last=mid;mid=(low+high)/2;if(mid*mid>number)high=mid;else low=mid;}while(fabs(mid-last)>1e-5);return mid;
}
double sqrt1(double number,double x)
{double y=(x+number/x)/2;return fabs(y-x)<0.001?y:sqrt1(number,y);
}
float sqrt2(float x)
{float xhalf = 0.5 * x;int i = *(int*)&x; // get bits for floating valuei = 0x5f3759df - (i >> 1); // gives initial guess//现在float最优魔值是0x5f375a86 所以上面的代码可以用  i = 0x5f375a86 - (i >> 1); 替换x = *(float*)&i; // convert bits back to floatx = x * (1.5 - xhalf * x * x); // 1st Newton stepx = x * (1.5 - xhalf * x * x); // 2nd Newton stepreturn x;
}
double sqrt3(double number)
{__int64 i;double x2, y;const double threehalfs = 1.5F;x2 = number * 0.5F;y  = number;i  = * ( __int64 * ) &y;i  = 0x5fe6ec85e7de30da - ( i >> 1 );y  = * ( double * ) &i;y  = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration//y  = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iterationreturn y;
}

在这里插入图片描述


http://chatgpt.dhexx.cn/article/YmB7C8ZC.shtml

相关文章

word中首字母大写问题处理

和word中的大多数显示问题相关&#xff0c;它的处理也是在文件——选项中处理&#xff0c;具体处理如图所示。

word中输入英文字母的时候,自动首字母大写,如何解决(以WPS为例)

我们在使用word编辑文档的时候&#xff0c;有的时候需要输入英文&#xff0c;但是却出现了输入一个英文&#xff0c;然后再按一下空格键&#xff0c;首字母自动变成大写的情况&#xff0c;那么现在就来学习一下如何解决这个问题 如图所示&#xff0c;输入单词&#xff0c;首字…

Word2003取消首字母大写方法

打开Word2003文档&#xff0c;编辑菜单栏的“工具”下拉列表中的“自动更正选项”&#xff0c;在弹出的“自动更正”窗口中将“句首字母大写”前面的钩取消&#xff0c;然后确定即可 提示&#xff1a;大家可以看到上图中还有表格单元格的首字母大写、英文日期第一个字母大写、更…

C语言编写取单词首字母,C语言练习之单词首字母大写

/* *Copyright(c) 2016,烟台大学计算机学院 *All rights reserved. *作 者&#xff1a;刘金石 *完成日期&#xff1a;2016年4月22日 *版本 号&#xff1a;v1.0 *问题描述&#xff1a;字符串中每个单词首字母变大写 */ #include int main() { int i; int word; char str[200]; …

word首字母不默认大写

这样在word里打一行英文时 首字母就不会默认大写 ------------------------------------------- 1. 2. 3.

word文档开头首字母取消自动检查大写

1、在word中先输入文本 2、打开菜单栏->审阅->拼写和语法 3、打开选项按钮 4、打开自动更正选项 里面可以修改文档中是否检查大写以及表格中是否检查大写。

word文档取消英文首字母大写

word文档取消英文首字母大写 这里我是用的OneNote做为演示&#xff0c;word文档是一样的操作 1、点击文件&#xff0c;再选择选项 2、进入校对&#xff0c;再选择自动更正选择 3、取消句首字母大写&#xff0c;再点击确定

【word基础】如何取消word首字母大写

转载于:https://www.cnblogs.com/xphdbky/p/7604566.html

word2016取消首字母大写 带图详细讲解

文件-->选项-->校对-->自动更正选项-->句首字母大写&#xff08;对勾去掉&#xff09; operation is over.

java首字母变大写_Java 首字母转大写

1.代码实现 /* * 首字母转大写 * attention: * date: 2020年11月17日 0017 14:51 * param: word 待转换字符串 * return: java.lang.String 首字母转成了大写 */ public static String convertInitialUpper(String word) { if (StringUtils.isEmpty(word)) return ""…

c语言将首字母变大写,c语言问题 将首字母变为大写

#include int main() { int i; int word; char str[200]; printf("请输入字符串:"); while(gets(str)!NULL) { printf("修改后的字符串为:"); word0; for(i0;str!\0;i) { if(str) { word0; printf(""); } else if(word0) { word1; strstr-32; pr…

怎么取消和设置Word中首字母大写

①打开Word文档 ②单击Word文档的“ 文件 ”选项卡&#xff08;左上角&#xff09; ③在侧栏中选择“选项” ④单机“编辑” ⑤勾选或放弃勾选就可以对其进行设置(操作完成后不要忘记点击“确定”&#xff09;

取消Word自动首字母大写步骤

前言 有时候在Word中输入英文字符时首字母会自动大写&#xff0c;但是这并不是我们想要的结果&#xff0c;本文是取消首字母大写的步骤。 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 第四步&#xff1a;

world 如何输入英文时取消首字母大写

1.打开Word文档&#xff0c;找到文档左上方的“文件”选项&#xff0c;点击“文件”选项&#xff1b; 2.点击“选项”&#xff0c;找到校对/编辑&#xff1b; 3.“找到自动更正”&#xff0c;并取消“首字符大写”的选项就可以了

去掉wps的word中首字母大写

左上角文件——>选择最下面的“选项”——>选择弹窗中的“编辑”——>把红框中的勾去掉即可

office365 word如何关闭首字母大写

问题 在Office365中无论写什么字母&#xff0c;首字母永远会自动变成大写的&#xff0c;无论你需要不需要&#xff01; 解决 1、打开word&#xff0c;点击【文件】>>【选项】 2、点击【样对】>> 【自动更正选项】 3、根据需要&#xff0c;取消【句首字母大写】和…

WPS中的word如何取消英文首字母大写

不知道你是不是一直也有这样的烦恼&#xff0c;记笔记的时候&#xff0c;特别是有时候敲代码&#xff0c;总是敲完一个单词&#xff0c;摁下空格就直接首字母变成大写了,就像下图一样~~~~ 那我们可以在wps中&#xff0c;先点击左上角的文件按钮。 再往下拉找到选项按钮。 点…

如何关闭Word自带的首个字母大写功能

三妹的 Word 版本是&#xff1a; 该版本自动打开了句首字母大写功能&#xff0c;但是我因为要记录一些代码相关的东西&#xff0c;根本不需要自动大写&#xff0c;大写之后反而不是我的代码了&#xff0c;所以急需把它关掉。 步骤如下&#xff1a; 1、找到菜单栏中的 ”工具“…