Example #1
0
        private TReal CommonRealType(TArithmetic x)
        {
            int rank = Math.Max(Rank, x.Rank);

            if (rank == TLDouble.Instance.Rank)
            {
                return(TLDouble.Instance);
            }
            if (rank == TDouble.Instance.Rank)
            {
                return(TDouble.Instance);
            }
            if (rank == TSingle.Instance.Rank)
            {
                return(TSingle.Instance);
            }

            /// Otherwise, the integer promotions are performed on both operands.
            /// Since both this and x are integer types, their promoted types are also integer types.
            TInteger a = IntPromote() as TInteger;
            TInteger b = x.IntPromote() as TInteger;

            /// Then the following rules are applied to the promoted operands.
            /// 1. If both operands have the same type, then no further conversion is needed.
            if (a.Equals(b))
            {
                return(a);
            }

            /// 2. Otherwise, if both operands have signed integer types or both have unsigned integer types,
            ///    the operand with the type of lesser integer conversion rank is converted to the type of the
            ///    operand with greater rank.
            if (a.IsSigned == b.IsSigned)
            {
                return(a.Rank > b.Rank ? a : b);
            }

            /// 3. Otherwise, if the operand that has unsigned integer type has rank greater or equal to the
            ///    rank  of the type of the other operand, then the operand with signed integer type is converted
            ///    to the type of the operand with unsigned integer type.
            TInteger u = a.IsSigned ? b : a;    // The unsigned integer type.
            TInteger s = a.IsSigned ? a : b;    // The signed integer type.

            if (u.Rank >= s.Rank)
            {
                return(u);
            }

            /// 4. Otherwise, if the type of the operand with signed integer type can represent all of the values
            ///    of the type of the operand with unsigned integer type, then the operand with unsigned integer type
            ///    is converted to the type of the operand with signed integer type.
            if (u.MAX < s.MAX && u.MIN > s.MIN)
            {
                return(s);
            }

            /// 5. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the
            ///    operand with signed integer type.
            return(s.Unsigned);
        }
Example #2
0
        public override TArithmetic UsualArithConversion(TUnqualified other)
        {
            if (!other.IsArithmetic)
            {
                throw new ArgumentException(string.Format("Usual arithmetic conversion should be performed on arithmetic types, not {0}!", other));
            }
            TArithmetic x = other as TArithmetic;

            // First determine a common real type.
            TReal crt = CommonRealType(x);

            // Check if both type domain are real.
            if (TypeDomain() == TDomain.REAL && other.TypeDomain() == TDomain.REAL)
            {
                return(crt);
            }
            else
            {
                // Convert the complex domain.
                return(crt.Complex);
            }
        }