平方根(sqrt)算法

最近听说开平方算法挺难写,自己思考一下确实这些库函数只是一直在用,但是很少去思考如何实现的,sqrt在排序中使用频率非常的高,所以就研究了一下。大概有三种实现方式。

一、用二分的方法

每次用中间数就试,如果大就到左区间选取中间数试,如果小就到右区间找中间数试,采用不断逼近的方式计算平方根,这种方式迭代次数有点多,且每次试验都要进行运算,效率不是很高,但是思路简单,巧妙的运用了二分的方法。

#define eps 0.00000001
float SqrtByBisection(float n)
{
    //小于0的按照你需要的处理
    if(n < 0)
        return n;
    float mid,last;
    float low,up;
    low=0,up=n;
    mid=(low+up)/2;
    do
    {
        if(mid*mid>n)
            up=mid;
        else
            low=mid;
        last=mid;
        mid=(up+low)/2;
    }
    //精度控制
    while(fabs(mid-last) > eps);
    return mid;
}

二、牛顿迭代法

这种方式的原理就是通过f(x) = x^2 - a = 0 的切线来逼近x^2 -a =0的的根,根号a就是f(x) =0的一个正实根,这个函数的导数是2x,也就是切线的斜率是2x,也就是x-f(x)/2x是比x更接近的近似值,带人方程得到f(x) = (x+a/x) / 2是更近似的值

float SqrtByNewton(float x)
{
 float val = x;//最终
 float last;//保存上一个计算的值
 do
 {
  last = val;
  val =(val + x/val) / 2;
 }while(fabs(val-last) > 0.0001);
 return val;
}

三、神一样的算法

float InvSqrt(float x)
{
 float xhalf = 0.5f*x;
 int i = *(int*)&x; // get bits for floating VALUE
 i = 0x5f3759df - (i>>1); // gives initial guess y0
 x = *(float*)&i; // convert bits BACK to float
 x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
 return x;
}

这个算法是卡马克(quake3作者)实现的,他真正牛B的地方是他选择了一个神秘的常数0x5f3759df 来计算那个猜测值,也是采用牛顿迭代法,但是选择的常数是绝妙的,能降上面的牛顿迭代法效率提高四倍,有空一定要拜读一下quake3的源代码,我在资源中放了一份欢迎下载

时间: 2024-10-24 02:26:51

平方根(sqrt)算法的相关文章

[转]講講 John Carmack 的快速反平方根演算法

講講 John Carmack 的快速反平方根演算法 原地址http://213style.blogspot.com/2014/07/john-carmack.html 本篇的主題很簡單,講講怎麼快速計算 反平方根 圖1. 反平方根函數,但是要如何快速計算此式呢? 反平方根運算在 3D 圖形領域占有重要地位,主要用於計算 光源 與 反射,運算過程中 需要計算 Normalized Vector,這時就需要進行反平方根運算,因為在 1990 年以前可沒有 特殊的硬體可以直接處理 T&L,直到有名的

C语言之linux内核实现平方根计算算法

关于平方根的计算,在linux内核中也有实现,就像math.h数学库里的sqrt这个函数一样. 平方根的公式定义: 如果一个非负数x的平方等于a,即 , ,那么这个非负数x叫做a的算术平方根.a的算术平方根记为 ,读作"根号a",a叫做被开方数(radicand).求一个非负数a的平方根的运算叫做开平方.结论:被开方数越大,对应的算术平方根也越大(对所有正数都成立). 一个正数如果有平方根,那么必定有两个,它们互为相反数.显然,如果我们知道了这两个平方根的一个,那么就可以及时的根据相反

一个求解平方根的算法题

1. 问题描述 问题是这样子的,给定一个数a,求解这个数的平方根,要求精度f<0.0001. 好久没有操刀实现算法代码了,今天就来写一个小的,后续算法依旧是研究的重点.比较软件中,算法是核心是灵魂啊! 2. 算法分析 说起来,这个算法题其实不是太麻烦,主要采取的就是不断试探,逼近真是目标值的思路,最容易想到的就是,不断的折半逼近,有点类似二分的思想.同时,一个重要的思想: 1. 设目标值平方根为Se 2. 待求解的输入数据为St 3. |Se*Se - St| < f*f 4. 求出一个Se*

leetcode 69. x 的平方根(Sqrt(x))

目录 题目描述: 示例 1: 示例 2: 解法: 题目描述: 实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 2: 输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去. 解法: class Solution { public: int mySqrt(int x) { if(x == 0 |

求平方根关键算法

求n以内(不包括n)同时能被3和7整除的所有自然数之和的平方根s,然后将结果s输出.例如若n为1000时,则s=153.909064. 注意:使用循环语句结构实现. ②n由键盘输入,且100 ≤ n ≤10000. package seven; import java.util.Scanner; public class two { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System

最快的开平方 sqrt 算法,供赏析

绝妙之处,没有使用循环. [email protected]:~/lab$ cat main.c  #include "stdio.h" float SqrtByCarmack( float number )   {       int i;       float x2, y;       const float threehalfs = 1.5F;          x2 = number * 0.5F;       y  = number;       i  = * ( int 

c 自定义sqrt算法。

转载自:http://www.examw.com/biancheng/c/194822/ #include <stdio.h> #include <math.h> #include <stdlib.h> #define ACC 0.000000001 double newSqrt(double n) { double low, high, mid, tmp; if(n > 1) { low = 1; high = n; } else { low = n; high

求平方根的算法 牛顿迭代法和二分法

牛顿法: public double sqr(double n){ double x=n,y=0.0; while (Math.abs(x-y)>0.0001){ y=x; x=(x+n/x)/2; } return x; } 设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f'(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f'(x0),称x1为r的一次近似值. 过点(x1,

Leetcode 69. Sqrt(x) 解题报告【C库函数sqrt(x)模拟-求平方根】

69. Sqrt(x) Total Accepted: 93296 Total Submissions: 368340 Difficulty: Medium 提交网址: https://leetcode.com/problems/sqrtx/ Implement int sqrt(int x). Compute and return the square root of x. 分析: 解法1:牛顿迭代法(牛顿切线法) Newton's Method(牛顿切线法)是由艾萨克·牛顿在<流数法>(M

求平方根算法 Heron’s algorithm

求平方根问题 概述:本文介绍一个古老但是高效的求平方根的算法及其python实现,分析它为什么可以快速求解,并说明它为何就是牛顿迭代法的特例. 问题:求一个正实数的平方根. 给定正实数 \(m\),如何求其平方根\(\sqrt{m}\)? 你可能记住了一些完全平方数的平方根,比如\(4, 9, 16, 144, 256\)等.那其它数字(比如\(105.6\))的平方根怎么求呢? 实际上,正实数的平方根有很多算法可以求.这里介绍一个最早可能是巴比伦人发现的算法,叫做Heron's algorit