在C#中使用泛型创建数学库

在C#中使用泛型创建数学库,第1张

在C#中使用泛型创建数学库

这是一种相对简单的抽象 *** 作员的方法。

    abstract class MathProvider<T>    {        public abstract T Divide(T a, T b);        public abstract T Multiply(T a, T b);        public abstract T Add(T a, T b);        public abstract T Negate(T a);        public virtual T Subtract(T a, T b)        { return Add(a, Negate(b));        }    }    class DoubleMathProvider : MathProvider<double>    {        public override double Divide(double a, double b)        { return a / b;        }        public override double Multiply(double a, double b)        { return a * b;        }        public override double Add(double a, double b)        { return a + b;        }        public override double Negate(double a)        { return -a;        }    }    class IntMathProvider : MathProvider<int>    {        public override int Divide(int a, int b)        { return a / b;        }        public override int Multiply(int a, int b)        { return a * b;        }        public override int Add(int a, int b)        { return a + b;        }        public override int Negate(int a)        { return -a;        }    }    class Fraction<T>    {        static MathProvider<T> _math;        // Notice this is a type constructor.  It gets run the first time a        // variable of a specific type is declared for use.        // Having _math static reduces overhead.        static Fraction()        { // This part of the pre might be cleaner by once // using reflection and finding all the implementors of // MathProvider and assigning the instance by the one that // matches T. if (typeof(T) == typeof(double))     _math = new DoubleMathProvider() as MathProvider<T>; else if (typeof(T) == typeof(int))     _math = new IntMathProvider() as MathProvider<T>; // ... assign other options here. if (_math == null)     throw new InvalidOperationException(         "Type " + typeof(T).ToString() + " is not supported by Fraction.");        }        // Immutable impementations are better.        public T Numerator { get; private set; }        public T Denominator { get; private set; }        public Fraction(T numerator, T denominator)        { // We would want this to be reduced to simpilest terms. // For that we would need GCD, abs, and remainder operations // defined for each math provider. Numerator = numerator; Denominator = denominator;        }        public static Fraction<T> operator +(Fraction<T> a, Fraction<T> b)        { return new Fraction<T>(     _math.Add(       _math.Multiply(a.Numerator, b.Denominator),       _math.Multiply(b.Numerator, a.Denominator)),     _math.Multiply(a.Denominator, b.Denominator));        }        public static Fraction<T> operator -(Fraction<T> a, Fraction<T> b)        { return new Fraction<T>(     _math.Subtract(       _math.Multiply(a.Numerator, b.Denominator),       _math.Multiply(b.Numerator, a.Denominator)),     _math.Multiply(a.Denominator, b.Denominator));        }        public static Fraction<T> operator /(Fraction<T> a, Fraction<T> b)        { return new Fraction<T>(     _math.Multiply(a.Numerator, b.Denominator),     _math.Multiply(a.Denominator, b.Numerator));        }        // ... other operators would follow.    }

如果无法实现所使用的类型,则将在运行时而不是编译时失败(这很糟糕)。实现的定义

MathProvider<T>
始终是相同的(也很糟糕)。我建议您只是避免在C#中执行此 *** 作,而应使用F#或其他更适合此抽象级别的语言。

编辑:
修复了加法和减法的定义

Fraction<T>
。另一个有趣且简单的事情是实现在抽象语法树上运行的MathProvider。这个想法立即指向做诸如自动区分的事情:http : //conal.net/papers/beautiful-
differentiation/



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4905161.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存