/// <summary> /// /// </summary> /// <param name="number1"></param> /// <param name="number2"></param> /// <param name="setValueIndicated">this is true if the return value is a clone and not the /// same instance as number1</param> /// <returns></returns> private static INumeric Add(INumeric number1, INumeric number2, out bool isReplace) { //the default value is false, as most cases don't need a clone operation isReplace = false; if (number1 == null) { isReplace = true; return number2; } if (number2 == null) return number1; INumeric rv = null; //determine the longer number bool? num1IsLonger = Numeric.AbsoluteValueCompare(number1.As<Numeric>(), number2.As<Numeric>()); //note: below we clone the 2nd arg if it is being modified as part of the operation //we don't clone the 1st arg as it is if (number1.IsPositive && number2.IsPositive) { rv = Increment(number1, number2); } else if (number1.IsPositive && number2.IsPositive == false) { switch (num1IsLonger) { case null: rv = Decrement(number1, number2); break; case true: rv = Decrement(number1, number2); break; case false: isReplace = true; var cloneNum2 = number2.Clone(); rv = Decrement(cloneNum2, number1); rv.As<Numeric>().IsPositive = false; break; } } else if (number1.IsPositive == false && number2.IsPositive) { switch (num1IsLonger) { case null: rv = Decrement(number1, number2); break; case true: rv = Decrement(number1, number2); break; case false: isReplace = true; rv = Decrement(number2.Clone(), number1); rv.As<Numeric>().IsPositive = true; break; } } else if (number1.IsPositive == false && number2.IsPositive == false) { rv = Increment(number1, number2); rv.As<Numeric>().IsPositive = false; } return rv; }
public void Subtract(INumeric numeric) { if (numeric == null) return; //if (!this.HasCompatibleNumberSystem(numeric)) // throw new InvalidOperationException("incompatible number system"); numeric.As<Numeric>().SwitchSign(); bool isClone = false; var val = Add(this, numeric, out isClone); numeric.As<Numeric>().SwitchSign(); //we don't want to return a modified arg if (isClone) this.As<Numeric>().SetValue(val); }