Пример #1
0
		public void NumberTest()
		{
			var two = new Integer(2);
			Assert.AreEqual(2, two.Value);
			Assert.AreEqual("2", two.ToString());

			var twopointfour = new Float(2.4);
			Assert.AreEqual(2.4, twopointfour.Value);
			Assert.AreEqual("2.4", twopointfour.ToString());
		}
Пример #2
0
		internal static bool IsConstant(Evaluatable expression, out Number value)
		{
			var factor = Factorizer.ToFactor(expression);
			if (factor is AlphabeticFactor)
			{
				var name = ((AlphabeticFactor)factor).Value;

				if (Constants.IsNamedConstant(name))
				{
					value = new Float(Constants.Get(name));
					return true;
				}
			}

			value = Integer.Zero;
			return false;
		}
Пример #3
0
		internal static bool IsWholeNumber(Float f)
		{
			return IsWholeNumber(f.Value);
		}
Пример #4
0
		private static bool IsNumber(Component component, out Number number)
		{
			if (component is SingleFactorComponent)
			{
				var sfc = (SingleFactorComponent)component;
				if (sfc.Factor is NumericFactor)
				{
					var nf = (NumericFactor)sfc.Factor;
					number = nf.Number;
					return true;
				}
			}

			if (component is IntegerFraction)
			{
				var inf = (IntegerFraction)component;
				if (inf.Denominator == 1)
				{
					number = new Integer(inf.Numerator * (inf.IsNegative ? -1 : 1));
					return true;
				}
			}

			if (component is ComponentList)
			{
				var cl = (ComponentList)component;
				if (cl.Factors.Count == 1)
				{
					var factor = cl.Factors[0];
					if (factor.Factor is NumericFactor)
					{
						if (factor.IsInNumerator)
						{
							number = ((NumericFactor)factor.Factor).Number;
							return true;
						}

						var denom = ((NumericFactor)factor.Factor).Number;
						if (denom is Float)
						{
							number = new Float(1 / ((Float)denom).ValueAsFloat());
							return true;
						}
					}
				}
			}

			number = null;
			return false;
		}
Пример #5
0
		protected override Expression InnerEvaluate(params Expression[] parameters)
		{
			var left = parameters[0].Evaluate();
			var right = parameters[1].Evaluate();

			Number leftNumber;
			Number rightNumber;

			if ((Common.IsConstant(left, out leftNumber) && Common.IsFloat(right, out rightNumber)) ||
				(Common.IsFloat(left, out leftNumber) && Common.IsConstant(right, out rightNumber)) ||
				(Common.IsNumber(left, out leftNumber) && Common.IsNumber(right, out rightNumber)))
			{
				return Expressionizer.ToExpression(new NumericFactor(leftNumber ^ rightNumber));
			}

			// Anything raised to 1 is itself
			if (Common.IsNumber(right, out rightNumber) && Math.Abs(rightNumber.ValueAsFloat() - 1) < Constants.Tolerance)
			{
				return left;
			}

			// Anything raised to 0 is 1
			if (Common.IsNumber(right, out rightNumber) && Math.Abs(rightNumber.ValueAsFloat()) < Constants.Tolerance)
			{
				return Expressionizer.ToExpression(new NumericFactor(new Integer(1)));
			}
			
			ExpressionList leftList;
			ExpressionList rightList;

			if (Common.IsList(left, out leftList))
			{
				return Evaluate(leftList, right);
			}

			if (Common.IsList(right, out rightList))
			{
				return Evaluate(rightList, left);
			}

			IntegerFraction leftFraction;
			IntegerFraction rightFraction;

			if (Common.IsNumber(left, out leftNumber) && Common.IsIntegerFraction(right, out rightFraction))
			{
				// Special case: negative left ^ fractional right (any number with a decimal portion) is non-real
				if (leftNumber.IsNegative && rightFraction.Denominator > 1)
				{
					throw new NonRealResultException();
				}

				if (leftNumber is Integer)
				{
					var result = new Float(leftNumber.ValueAsFloat()) ^ rightFraction;
					if (Number.IsWholeNumber(result))
					{
						return Expressionizer.ToExpression(new NumericFactor(new Integer((int)result.ValueAsFloat())));
					}

					return AsExpression(left, right);
				}

				return Expressionizer.ToExpression(leftNumber ^ rightFraction);
			}

			if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsNumber(right, out rightNumber))
			{
				// Special case: negative left ^ fractional right (any number with a decimal portion) is non-real
				if (leftFraction.IsNegative && !Number.IsWholeNumber(rightNumber))
				{
					throw new NonRealResultException();
				}

				return Expressionizer.ToExpression(leftFraction ^ rightNumber);
			}

			if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsIntegerFraction(right, out rightFraction))
			{
				// Special case: negative left ^ fractional right (any number with a decimal portion) is non-real
				if (leftFraction.IsNegative && rightFraction.Denominator > 1)
				{
					throw new NonRealResultException();
				}

				return Expressionizer.ToExpression(leftFraction ^ rightFraction);
			}

			if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsNumber(right, out rightNumber))
			{
				// Special case: negative left ^ fractional right (any number with a decimal portion) is non-real
				if (leftFraction.IsNegative && !Number.IsWholeNumber(rightNumber))
				{
					throw new NonRealResultException();
				}

				if (rightNumber is Integer)
				{
					var rightInteger = (Integer)rightNumber;
					var result = leftFraction ^ rightInteger;
					return Expressionizer.ToExpression(result);
				}
				else
				{
					var rightDouble = (Float)rightNumber;
					var result = leftFraction ^ rightDouble;
					return Expressionizer.ToExpression(new NumericFactor(result));
				}
			}

			return AsExpression(left, right);
		}