Example #1
0
            /// <summary>
            /// Performs so-called downcasting, an attempt to narrow a number's affiliation to a number set
            /// It attempts to cast ComplexNumber to RealNumber, RealNumber to RationalNumber, RationalNumber to IntegerNumber
            /// </summary>
            /// <param name="a">
            /// Number to downcast
            /// </param>
            /// <returns>
            /// Downcasted or kept Number
            /// </returns>
            public static Number Downcast(Number a)
            {
                if (!MathS.Settings.DowncastingEnabled)
                {
                    return(a);
                }
                var res = SuperSwitch(
                    num => (Result: num[0], Continue: false),
                    (num) =>
                {
                    if (!(a as RealNumber).IsDefinite())
                    {
                        return(Result: a, Continue: false);
                    }
                    var ratnum = num[0];
                    var gcd    = Utils.GCD(ratnum.Denominator.Value, ratnum.Numerator.Value);
                    ratnum     = new RationalNumber(
                        new IntegerNumber(ratnum.Numerator.Value / gcd),
                        new IntegerNumber(ratnum.Denominator.Value / gcd)
                        );
                    if (EDecimalWrapper.IsEqual(ratnum.Denominator.Value, 1))
                    {
                        return(Result: ratnum.Numerator, Continue: false);
                    }
                    else
                    {
                        return(Result: ratnum, Continue: false);
                    }
                },
                    (num) =>
                {
                    if (!(a as RealNumber).IsDefinite())
                    {
                        return(Result: a, Continue: false);
                    }
                    var realnum = num[0];

                    if (TryCastToInt(realnum.Value, out var intres))
                    {
                        return(Result: new IntegerNumber(intres), Continue: false);
                    }

                    var attempt = FindRational(realnum.Value, MathS.Settings.FloatToRationalIterCount);
                    if (attempt is null ||
                        Number.Abs(attempt.Numerator) > MathS.Settings.MaxAbsNumeratorOrDenominatorValue ||
                        Number.Abs(attempt.Denominator) > MathS.Settings.MaxAbsNumeratorOrDenominatorValue)
                    {
                        return(Result: realnum, Continue: false);
                    }