Function 平方根函数是如何实现的?

Function 平方根函数是如何实现的?,function,math,square-root,Function,Math,Square Root,平方根函数是如何实现的?在英特尔硬件上,它通常在硬件SQRT指令之上实现。有些库直接使用该结果,有些库可能会对其进行几轮牛顿优化,以使其在极端情况下更精确。要计算平方根(不使用内置的math.sqrt函数): SquareRootFunction.java public class SquareRootFunction { public double squareRoot(double value,int decimalPoints) { int firstPa

平方根函数是如何实现的?

在英特尔硬件上,它通常在硬件SQRT指令之上实现。有些库直接使用该结果,有些库可能会对其进行几轮牛顿优化,以使其在极端情况下更精确。

要计算平方根(不使用内置的math.sqrt函数):

SquareRootFunction.java

public class SquareRootFunction {

    public double squareRoot(double value,int decimalPoints)
    {
        int firstPart=0;


        /*calculating the integer part*/
        while(square(firstPart)<value)
        {
            firstPart++;            
        }

        if(square(firstPart)==value)
            return firstPart;
        firstPart--;

        /*calculating the decimal values*/
        double precisionVal=0.1;
        double[] decimalValues=new double[decimalPoints];
        double secondPart=0;

        for(int i=0;i<decimalPoints;i++)
        {
            while(square(firstPart+secondPart+decimalValues[i])<value)
            {
                decimalValues[i]+=precisionVal;
            }

            if(square(firstPart+secondPart+decimalValues[i])==value)
            {
                return (firstPart+secondPart+decimalValues[i]);
            }

            decimalValues[i]-=precisionVal;
            secondPart+=decimalValues[i];
            precisionVal*=0.1;
        }

        return(firstPart+secondPart);

    }


    public double square(double val)
    {
        return val*val;
    }

}
import java.util.Scanner;

public class MainApp {

public static void main(String[] args) {

    double number;
    double result;
    int decimalPoints;
    Scanner in = new Scanner(System.in);

    SquareRootFunction sqrt=new SquareRootFunction();   
    System.out.println("Enter the number\n");               
    number=in.nextFloat();  

    System.out.println("Enter the decimal points\n");           
    decimalPoints=in.nextInt();

    result=sqrt.squareRoot(number,decimalPoints);

    System.out.println("The square root value is "+ result);

    in.close();

    }

}

用C语言简单实现++

双根(双n){
//最大值和最小值用于考虑小于1的数字
双低=最小值(1,n),高=最大值(1,n),中;
//将边界更新为偏离目标10倍
而(100*lo*lon)hi*=0.1;
对于(int i=0;i<100;i++){
中期=(低+高)/2;
如果(mid*mid==n)返回mid;
如果(mid*mid>n)hi=mid;
否则lo=中间;
}
中途返回;
}
请注意,
虽然
循环在二进制搜索中最为常见,但我个人更喜欢在处理十进制数时使用
for
,这样可以节省一些特殊情况的处理,并从像
1000
甚至
500
这样的小循环中获得相当准确的结果(为了安全起见,几乎所有数字的结果都是一样的)

编辑:针对各种-特殊用途-专门用于计算平方根的方法,请查看此文件

编辑2:应用@jorgbrown建议的更新,在输入小于1的情况下修复函数。此外,应用优化,使目标根的边界偏离10倍。FDLIBM(可自由分发的LIBM)有一个非常好的sqrt文档版本

有一个版本使用整数算术和一次修改一位的递归公式

另一种方法使用牛顿法。它从一些黑魔法和查找表开始,得到前8位,然后应用递推公式

 y_{i+1} = 1/2 * ( y_i + x / y_i)
其中x是我们开始使用的数字。这是Heron方法的最早版本。它可以追溯到公元第一个世纪亚历山德拉的英雄

还有另一种方法称为or reciproot。它使用一些“邪恶的浮点位级黑客”来查找1/sqrt(x)的值。
i=0x5f3759df-(i>>1);
它利用浮点的二进制表示形式,使用尾数和指数。如果我们的数字x是(1+m)*2^e,其中m是尾数,e是指数,结果y=1/sqrt(x)=(1+n)*2^f。取对数

lg(y) = - 1/2 lg(x)
f + lg(1+n) = -1/2 e - 1/2 lg(1+m)
我们看到结果的指数部分是数字的指数的-1/2。黑魔法基本上对指数进行位移位,并对尾数使用线性近似

一旦你有了一个好的一次近似,你就可以使用牛顿的方法来获得更好的结果,并最终进行一些位级的工作来修复最后一个数字。

sqrt();幕后函数

它总是检查图形中的中点

现在,如果你在16或4中输入任何东西,比如sqrt(10)=

它找到2和4的中点,即e=x,然后再次找到x和4的中点(不包括此输入中的下限)。它一次又一次地重复此步骤,直到得到完美答案,即sqrt(10)==3.16227766017。它位于b/w 2和4。所有这些内置函数都是使用微积分、微分和积分创建的。

long long int floorSqrt(long long int x)
long long int floorSqrt(long long int x) 
{
    long long r = 0;
    while((long)(1<<r)*(long)(1<<r) <= x){
        r++;
    }
    r--;
    long long b = r -1;
    long long ans = 1 << r;
    while(b >= 0){
        if(((long)(ans|1<<b)*(long)(ans|1<<b))<=x){
            ans |= (1<<b);
        }
        b--;
    }
    return ans;
}
{ 长r=0;
而((long)(1这是牛顿算法的实现,请参见

func Sqrt(x float64)float64{
//让最初的猜测为1
z:=1.0

对于i:=1;i在Python中的实现: 根值的下限是此函数的输出。 示例:8的平方根为2.82842…,此函数将给出输出“2”

def mySqrt(x):
        # return int(math.sqrt(x))
        if x==0 or x==1:
            return x
        else:
            start = 0
            end = x  
            while (start <= end):
                mid = int((start + end) / 2)
                if (mid*mid == x):
                    return mid
                elif (mid*mid < x):
                    start = mid + 1
                    ans = mid
                else:
                    end = mid - 1
            return ans
def mySqrt(x):
#返回整数(数学sqrt(x))
如果x==0或x==1:
返回x
其他:
开始=0
结束=x

而(开始有一种叫做巴比伦法的东西

static float squareRoot(float n)
{

    /*We are using n itself as 
    initial approximation This 
    can definitely be improved */
    float x = n;
    float y = 1;

    // e decides the accuracy level
    double e = 0.000001;
    while(x - y > e)
    {
        x = (x + y)/2;
        y = n/x;
    }
    return x;
}

有关更多信息,请链接:

因此,为了防止没有关于是否使用内置ceil或round函数的规范,下面是Java中使用牛顿-拉斐逊方法查找无符号数平方根的递归方法

public class FindSquareRoot {

    private static double newtonRaphson(double N, double X, double oldX) {

        if(N <= 0) return 0;

        if (Math.round(X) == Math.ceil(oldX))
            return X;

        return newtonRaphson(N, X - ((X * X) - N)/(2 * X), X);
    }

    //Driver method
    public static void main (String[] args) {
        System.out.println("Square root of 48.8: " + newtonRaphson(48.8, 10, 0));
    }
}
公共类FindSquareRoot{
专用静态双牛顿函数(双N,双X,双oldX){

如果(N我也在做一个sqrt函数,100000000次迭代需要14秒,与sqrt的1秒相比仍然是零

double mysqrt(double n)
{
    double x = n;
    int it = 4;
    if (n >= 90)
    {
        it = 6;
    }
    if (n >= 5000)
    {
        it = 8;
    }
    if (n >= 20000)
    {
        it = 10;
    }
    if (n >= 90000)
    {
        it = 11;
    }
    if (n >= 200000)
    {
        it = 12;
    }
    if (n >= 900000)
    {
        it = 13;
    }
    if (n >= 3000000)
    {
        it = 14;
    }
    if (n >= 10000000)
    {
        it = 15;
    }
    if (n >= 30000000)
    {
        it = 16;
    }
    if (n >= 100000000)
    {
        it = 17;
    }

    if (n >= 300000000)
    {
        it = 18;
    }
    if (n >= 1000000000)
    {
        it = 19;
    }

    for (int i = 0; i < it; i++)
    {
        x = 0.5*(x+n/x);
    }
    return x;
}

按照我在Golang的解决方案

package main

import (
   "fmt"
)

func Sqrt(x float64) float64 {
   z := 1.0 // initial guess to be 1
   i := 0
   for int(z*z) != int(x) { // until find the first approximation
      // Newton root algorithm
      z -= (z*z - x) / (2 * z)
      i++
   }
   return z
}

func main() {
   fmt.Println(Sqrt(8900009870))
}
遵循经典/通用解决方案

package main

import (
"fmt"
"math"
)

func Sqrt(num float64) float64 {
   const DIFF = 0.0001 // To fix the precision
   z := 1.0

   for {
      z1 := z - (((z * z) - num) / (2 * z))
      // Return a result when the diff between the last execution 
      // and the current one is lass than the precision constant
      if (math.Abs(z1 - z) < DIFF) {
         break
      }
      z = z1
   }

   return z
}


func main() {
   fmt.Println(Sqrt(94339))
}
主程序包
进口(
“fmt”
“数学”
)
func Sqrt(num float64)float64{
const DIFF=0.0001//用于固定精度
z:=1.0
为了{
z1:=z-((z*z)-num)/(2*z))
//当上次执行之间的差异
//当前值比精度常数小
if(数学绝对值(z1-z)
有关更多信息,请查看公式:根(数字,)==number^(根^(-depth)) 用法:根目录(编号,,) 示例:根(16,2)=sqrt(16)==4 示例:根(16,2,2)==sqrt(sqrt(16))==2 示例:根(64,3)==4 C#中的实现: 静态双根(双数字,双根=2f,双深度=1f) { 返回Math.Pow(number,Math.Pow(root,-depth)); }
用法:根(数字、根、深度)

示例:根(16,2)==sqrt(16)==4
示例:根(16,2,2)==sqrt(sqrt(16))==2
示例:根(64,3)==4

在C#中的实现:

double root(double number, double root, double depth = 1f)
{
    return number ^ (root ^ (-depth));
}
用法:Sqrt(数量、深度)

示例:Sqrt(16)==4
示例:Sqrt(8,
package main

import (
   "fmt"
)

func Sqrt(x float64) float64 {
   z := 1.0 // initial guess to be 1
   i := 0
   for int(z*z) != int(x) { // until find the first approximation
      // Newton root algorithm
      z -= (z*z - x) / (2 * z)
      i++
   }
   return z
}

func main() {
   fmt.Println(Sqrt(8900009870))
}
package main

import (
"fmt"
"math"
)

func Sqrt(num float64) float64 {
   const DIFF = 0.0001 // To fix the precision
   z := 1.0

   for {
      z1 := z - (((z * z) - num) / (2 * z))
      // Return a result when the diff between the last execution 
      // and the current one is lass than the precision constant
      if (math.Abs(z1 - z) < DIFF) {
         break
      }
      z = z1
   }

   return z
}


func main() {
   fmt.Println(Sqrt(94339))
}
Formula: root(number, <root>, <depth>) == number^(root^(-depth))

Usage: root(number,<root>,<depth>)

Example: root(16,2) == sqrt(16) == 4
Example: root(16,2,2) == sqrt(sqrt(16)) == 2
Example: root(64,3) == 4

Implementation in C#:

static double root(double number, double root = 2f, double depth = 1f)
{
    return Math.Pow(number, Math.Pow(root, -depth));
}
double root(double number, double root, double depth = 1f)
{
    return number ^ (root ^ (-depth));
}
double Sqrt(double number, double depth = 1) return root(number,2,depth);
constexpr unsigned int root(unsigned int x) {
  unsigned int i = 0;
  if (x >= 65536) {
    if ((i + 32768) * (i + 32768) <= x) i += 32768;
    if ((i + 16384) * (i + 16384) <= x) i += 16384;
    if ((i + 8192) * (i + 8192) <= x) i += 8192;
    if ((i + 4096) * (i + 4096) <= x) i += 4096;
    if ((i + 2048) * (i + 2048) <= x) i += 2048;
    if ((i + 1024) * (i + 1024) <= x) i += 1024;
    if ((i + 512) * (i + 512) <= x) i += 512;
    if ((i + 256) * (i + 256) <= x) i += 256;
  }
  if ((i + 128) * (i + 128) <= x) i += 128;
  if ((i + 64) * (i + 64) <= x) i += 64;
  if ((i + 32) * (i + 32) <= x) i += 32;
  if ((i + 16) * (i + 16) <= x) i += 16;
  if ((i + 8) * (i + 8) <= x) i += 8;
  if ((i + 4) * (i + 4) <= x) i += 4;
  if ((i + 2) * (i + 2) <= x) i += 2;
  if ((i + 1) * (i + 1) <= x) i += 1;
  return i;
}