c#Math.Sqrt实现

c#Math.Sqrt实现,c#,.net,math,frameworks,C#,.net,Math,Frameworks,最近我经常使用System.Math,前几天我在想,微软会如何在库中实现Sqrt方法。因此,我打开我的best mate Reflector并尝试在库中分解该方法,但结果显示: [MethodImpl(MethodImplOptions.InternalCall),ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static extern double Sqrt(double d); 那天,我有

最近我经常使用System.Math,前几天我在想,微软会如何在库中实现Sqrt方法。因此,我打开我的best mate Reflector并尝试在库中分解该方法,但结果显示:

[MethodImpl(MethodImplOptions.InternalCall),ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern double Sqrt(double d);
那天,我有史以来第一次意识到我的孩子是多么依赖于框架,吃东西


除了笑话之外,我想知道MS会使用什么样的算法来实现这种方法,或者换句话说,如果没有库支持,您将如何用C#编写自己的Math.Sqrt实现。

函数将转换为汇编指令。例如x87的
fsqrt
指令


您可以在软件中实现浮点数,但这很可能要慢得多。我认为对于Sqrt来说,迭代算法是典型的实现。

Google.com会给你比StackOverflow.com更多的答案

请查看此页面: 在上面的wiki页面的标题“二进制数字系统(基数2)”下可以找到一种算法

但是,软件实现将不会有效率。现代CPU在FPU中有数学函数的硬件实现。您只需调用处理器的正确指令(用汇编或机器语言)

public double Sqrt(int number)
{
双x=数字/2;
对于(inti=0;i<100;i++)x=(x+number/x)/2d;
返回x;
}

非常粗略的方法,但是如果我使用了一些更详细的方法,比如log方法,你可以问“我如何实现日志方法?”< /p> 你用反射镜或参考源找到的方法,其中的内部调用实际上是在CLR内部的C++中实现的。您可以从SSCLI20发行版获得这些的源代码。相关文件是clr/src/vm/ecall.cpp,它包含一个带有函数指针的方法名表,JIT编译器使用该表将调用地址直接嵌入生成的机器代码中。相关表格部分如下所示

FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
...
这会将您带到clr/src/classlibnative/float/comfloat.cpp

FCIMPL1_V(double, COMDouble::Sqrt, double d)
    WRAPPER_CONTRACT;
    STATIC_CONTRACT_SO_TOLERANT;

    return (double) sqrt(d);
FCIMPLEND
它只调用CRT函数。但x86抖动中并不是这样,请注意表声明中的“内在”。在SSLI20版本的抖动中,您不会发现它是一个简单的、不受专利限制的抖动。然而,配送服务确实将其转化为一种内在的:

double d = 2.0;
Console.WriteLine(Math.Sqrt(d));
转化为

00000008  fld         dword ptr ds:[0072156Ch] 
0000000e  fsqrt 
..etc

换句话说,Math.Sqrt()转换为单个浮点机器代码指令。查看有关如何轻松击败本机代码的详细信息。

要重新创建
System.Math.Sqrt
函数,只需执行以下操作:

publicstaticdoublesqrt(doublen)=>Math.Pow(n,1/2);

出于兴趣,我们的最佳伴侣将在3月份花费35美元……我不确定最低有效位是否正确。当然可以。这就是为什么我说它非常粗糙的原因,当然,你可以多次迭代以获得足够的误差,但是这会使算法的可读性降低
2d
2
作为
double
。它仍然是软件,即使它存储在硬件中并称为micro-program.Hsns,非常感谢您的深入回答。
00000008  fld         dword ptr ds:[0072156Ch] 
0000000e  fsqrt 
..etc