• .NET的Math类中的三角函数和双曲函数的代码是怎么写的?
  • 发布于 2个月前
  • 157 热度
    3 评论
最近因一个项目经常要用到一些数学算法,所以用Math类的次数会比较多一点,虽然只要正常调用Math类的方法就能很轻松的实现想要的计算结果,但是对于Math类内部的实现,我一直很好奇微软是怎么写的,不知道哪位大神知道Math类中的三角函数和双曲函数的代码是怎么写的?
用户评论
  • 曾颖
  • ILSpy 反编译Math 类
    namespace System
    {
        using System.Runtime.CompilerServices;
        using System.Runtime.ConstrainedExecution;
        using System.Runtime.InteropServices;
        using System.Runtime.Versioning;
        using System.Security;
    
        [__DynamicallyInvokable]
        public static class Math
        {
            private static double doubleRoundLimit = 1E+16;
            [__DynamicallyInvokable]
            public const double E = 2.7182818284590451;
            private const int maxRoundingDigits = 15;
            [__DynamicallyInvokable]
            public const double PI = 3.1415926535897931;
            private static double[] roundPower10Double = new double[] { 1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1E+15 };
    
            [__DynamicallyInvokable]
            public static decimal Abs(decimal value) => 
                decimal.Abs(value);
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Abs(double value);
            [__DynamicallyInvokable]
            public static short Abs(short value)
            {
                if (value >= 0)
                {
                    return value;
                }
                return AbsHelper(value);
            }
    
            [__DynamicallyInvokable]
            public static int Abs(int value)
            {
                if (value >= 0)
                {
                    return value;
                }
                return AbsHelper(value);
            }
    
            [__DynamicallyInvokable]
            public static long Abs(long value)
            {
                if (value >= 0L)
                {
                    return value;
                }
                return AbsHelper(value);
            }
    
            [CLSCompliant(false), __DynamicallyInvokable]
            public static sbyte Abs(sbyte value)
            {
                if (value >= 0)
                {
                    return value;
                }
                return AbsHelper(value);
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern float Abs(float value);
            private static short AbsHelper(short value)
            {
                if (value == -32768)
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
                }
                return -value;
            }
    
            private static int AbsHelper(int value)
            {
                if (value == -2147483648)
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
                }
                return -value;
            }
    
            private static long AbsHelper(long value)
            {
                if (value == -9223372036854775808L)
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
                }
                return -value;
            }
    
            private static sbyte AbsHelper(sbyte value)
            {
                if (value == -128)
                {
                    throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
                }
                return -value;
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Acos(double d);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Asin(double d);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Atan(double d);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Atan2(double y, double x);
            public static long BigMul(int a, int b) => 
                (a * b);
    
            [__DynamicallyInvokable]
            public static decimal Ceiling(decimal d) => 
                decimal.Ceiling(d);
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Ceiling(double a);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Cos(double d);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Cosh(double value);
            public static int DivRem(int a, int b, out int result)
            {
                result = a % b;
                return (a / b);
            }
    
            public static long DivRem(long a, long b, out long result)
            {
                result = a % b;
                return (a / b);
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Exp(double d);
            [__DynamicallyInvokable]
            public static decimal Floor(decimal d) => 
                decimal.Floor(d);
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Floor(double d);
            [__DynamicallyInvokable]
            public static double IEEERemainder(double x, double y)
            {
                if (double.IsNaN(x))
                {
                    return x;
                }
                if (double.IsNaN(y))
                {
                    return y;
                }
                double d = x % y;
                if (double.IsNaN(d))
                {
                    return double.NaN;
                }
                if ((d == 0.0) && double.IsNegative(x))
                {
                    return double.NegativeZero;
                }
                double num2 = d - (Abs(y) * Sign(x));
                if (Abs(num2) == Abs(d))
                {
                    double a = x / y;
                    if (Abs(Round(a)) > Abs(a))
                    {
                        return num2;
                    }
                    return d;
                }
                if (Abs(num2) < Abs(d))
                {
                    return num2;
                }
                return d;
            }
    
            [SecuritySafeCritical]
            private static unsafe double InternalRound(double value, int digits, MidpointRounding mode)
            {
                if (Abs(value) < doubleRoundLimit)
                {
                    double num = roundPower10Double[digits];
                    value *= num;
                    if (mode == MidpointRounding.AwayFromZero)
                    {
                        double num2 = SplitFractionDouble(&value);
                        if (Abs(num2) >= 0.5)
                        {
                            value += Sign(num2);
                        }
                    }
                    else
                    {
                        value = Round(value);
                    }
                    value /= num;
                }
                return value;
            }
    
            [SecuritySafeCritical]
            private static unsafe double InternalTruncate(double d)
            {
                SplitFractionDouble(&d);
                return d;
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Log(double d);
            [__DynamicallyInvokable]
            public static double Log(double a, double newBase)
            {
                if (double.IsNaN(a))
                {
                    return a;
                }
                if (double.IsNaN(newBase))
                {
                    return newBase;
                }
                if ((newBase != 1.0) && ((a == 1.0) || ((newBase != 0.0) && !double.IsPositiveInfinity(newBase))))
                {
                    return (Log(a) / Log(newBase));
                }
                return double.NaN;
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Log10(double d);
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static byte Max(byte val1, byte val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static decimal Max(decimal val1, decimal val2) => 
                decimal.Max(val1, val2);
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static double Max(double val1, double val2)
            {
                if (val1 > val2)
                {
                    return val1;
                }
                if (double.IsNaN(val1))
                {
                    return val1;
                }
                return val2;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static short Max(short val1, short val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static int Max(int val1, int val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static long Max(long val1, long val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static sbyte Max(sbyte val1, sbyte val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static float Max(float val1, float val2)
            {
                if (val1 > val2)
                {
                    return val1;
                }
                if (float.IsNaN(val1))
                {
                    return val1;
                }
                return val2;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static ushort Max(ushort val1, ushort val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static uint Max(uint val1, uint val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static ulong Max(ulong val1, ulong val2)
            {
                if (val1 < val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static byte Min(byte val1, byte val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static decimal Min(decimal val1, decimal val2) => 
                decimal.Min(val1, val2);
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static double Min(double val1, double val2)
            {
                if (val1 < val2)
                {
                    return val1;
                }
                if (double.IsNaN(val1))
                {
                    return val1;
                }
                return val2;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static short Min(short val1, short val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static int Min(int val1, int val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static long Min(long val1, long val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static sbyte Min(sbyte val1, sbyte val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static float Min(float val1, float val2)
            {
                if (val1 < val2)
                {
                    return val1;
                }
                if (float.IsNaN(val1))
                {
                    return val1;
                }
                return val2;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static ushort Min(ushort val1, ushort val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static uint Min(uint val1, uint val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [CLSCompliant(false), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), NonVersionable, __DynamicallyInvokable]
            public static ulong Min(ulong val1, ulong val2)
            {
                if (val1 > val2)
                {
                    return val2;
                }
                return val1;
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Pow(double x, double y);
            [__DynamicallyInvokable]
            public static decimal Round(decimal d) => 
                decimal.Round(d, 0);
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Round(double a);
            [__DynamicallyInvokable]
            public static decimal Round(decimal d, int decimals) => 
                decimal.Round(d, decimals);
    
            [__DynamicallyInvokable]
            public static decimal Round(decimal d, MidpointRounding mode) => 
                decimal.Round(d, 0, mode);
    
            [__DynamicallyInvokable]
            public static double Round(double value, int digits)
            {
                if ((digits < 0) || (digits > 15))
                {
                    throw new ArgumentOutOfRangeException("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
                }
                return InternalRound(value, digits, MidpointRounding.ToEven);
            }
    
            [__DynamicallyInvokable]
            public static double Round(double value, MidpointRounding mode) => 
                Round(value, 0, mode);
    
            [__DynamicallyInvokable]
            public static decimal Round(decimal d, int decimals, MidpointRounding mode) => 
                decimal.Round(d, decimals, mode);
    
            [__DynamicallyInvokable]
            public static double Round(double value, int digits, MidpointRounding mode)
            {
                if ((digits < 0) || (digits > 15))
                {
                    throw new ArgumentOutOfRangeException("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
                }
                if ((mode >= MidpointRounding.ToEven) && (mode <= MidpointRounding.AwayFromZero))
                {
                    return InternalRound(value, digits, mode);
                }
                object[] values = new object[] { mode, "MidpointRounding" };
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", values), "mode");
            }
    
            [__DynamicallyInvokable]
            public static int Sign(decimal value)
            {
                if (value < decimal.Zero)
                {
                    return -1;
                }
                if (value > decimal.Zero)
                {
                    return 1;
                }
                return 0;
            }
    
            [__DynamicallyInvokable]
            public static int Sign(double value)
            {
                if (value < 0.0)
                {
                    return -1;
                }
                if (value > 0.0)
                {
                    return 1;
                }
                if (value != 0.0)
                {
                    throw new ArithmeticException(Environment.GetResourceString("Arithmetic_NaN"));
                }
                return 0;
            }
    
            [__DynamicallyInvokable]
            public static int Sign(short value)
            {
                if (value < 0)
                {
                    return -1;
                }
                if (value > 0)
                {
                    return 1;
                }
                return 0;
            }
    
            [__DynamicallyInvokable]
            public static int Sign(int value)
            {
                if (value < 0)
                {
                    return -1;
                }
                if (value > 0)
                {
                    return 1;
                }
                return 0;
            }
    
            [__DynamicallyInvokable]
            public static int Sign(long value)
            {
                if (value < 0L)
                {
                    return -1;
                }
                if (value > 0L)
                {
                    return 1;
                }
                return 0;
            }
    
            [CLSCompliant(false), __DynamicallyInvokable]
            public static int Sign(sbyte value)
            {
                if (value < 0)
                {
                    return -1;
                }
                if (value > 0)
                {
                    return 1;
                }
                return 0;
            }
    
            [__DynamicallyInvokable]
            public static int Sign(float value)
            {
                if (value < 0f)
                {
                    return -1;
                }
                if (value > 0f)
                {
                    return 1;
                }
                if (value != 0f)
                {
                    throw new ArithmeticException(Environment.GetResourceString("Arithmetic_NaN"));
                }
                return 0;
            }
    
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Sin(double a);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Sinh(double value);
            [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
            private static extern unsafe double SplitFractionDouble(double* value);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
            public static extern double Sqrt(double d);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Tan(double a);
            [MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical, __DynamicallyInvokable]
            public static extern double Tanh(double value);
            [__DynamicallyInvokable]
            public static decimal Truncate(decimal d) => 
                decimal.Truncate(d);
    
            [__DynamicallyInvokable]
            public static double Truncate(double d) => 
                InternalTruncate(d);
        }
    }

  • 2018/3/26 9:04:00 [ 0 ] [ 0 ] 回复