/// <summary> /// Adding quantities with different storage types /// </summary> /// <typeparam name="Q">Second Quantity Type</typeparam> /// <param name="firstQuantity"></param> /// <param name="secondQuantity"></param> /// <returns></returns> public static AnyQuantity <T> Add <Q>(AnyQuantity <T> firstQuantity, AnyQuantity <Q> secondQuantity) { if (firstQuantity.Equals(secondQuantity)) { AnyQuantity <T> AQ = null; try { AQ = QuantityDimension.QuantityFrom <T>(firstQuantity.Dimension); //exception happen when adding two derived quantities together } catch (QuantityNotFoundException) { //keep the first quantity configuration. AQ = (AnyQuantity <T>)firstQuantity.Clone(); } T firstVal = (firstQuantity.Value); Q secondVal = (secondQuantity.Value); //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = MultiplyScalarByGeneric <Q>(stof.ConversionFactor, secondVal); } var expr = Expression.Add(Expression.Constant(firstVal), Expression.Constant(secondVal)); // Construct Lambda function which return one object. Expression <Func <T> > cq = Expression.Lambda <Func <T> >(expr); // compile the function Func <T> aqf = cq.Compile(); // execute the function T result = aqf(); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //assign the unit of first quantity to the result. AQ.Unit = firstQuantity.Unit; } AQ.Value = result; return(AQ); } else { throw new QuantitiesNotDimensionallyEqualException(); } }
public static AnyQuantity <T> Divide(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { //to preserve the units we make a derivedquantity with passed quantities // then we take the derived unit in temporary store // then we try to get strongly typed Quantity // then assign the unit to the generated quantity. // this way we won't have to know the unit system of the quantity. AnyQuantity <T> sec_qty = (AnyQuantity <T>)secondQuantity.Invert(); //this is a divide process we must make 1/exponenet :) AnyQuantity <T> qresult = (AnyQuantity <T>)ConstructDerivedQuantity(firstQuantity, sec_qty); try { qresult = QuantityDimension.QuantityFrom <T>(qresult.Dimension); } catch (QuantityNotFoundException) { } if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { qresult.Value = (T)(object)(((double)(object)firstQuantity.Value) * ((double)(object)sec_qty.Value)); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, sec_qty.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = (T)(object)(un.GetUnitOverflow() * ((double)(object)qresult.Value)); } } } else { qresult.Value = DivideGenericByGeneric(firstQuantity.Value, secondQuantity.Value); //check if any of the two quantities have a valid unit // to be able to derive the current quantity if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, sec_qty.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = MultiplyScalarByGeneric(un.GetUnitOverflow(), qresult.Value); } } } return(qresult); }
public static AnyQuantity <T> Multiply(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { AnyQuantity <T> qresult = (AnyQuantity <T>)ConstructDerivedQuantity <T>(firstQuantity, secondQuantity); try { //correct quantities and units qresult = QuantityDimension.QuantityFrom <T>(qresult.Dimension); } catch (QuantityNotFoundException) { } if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { qresult.Value = (T)(object)(((double)(object)firstQuantity.Value) * ((double)(object)secondQuantity.Value)); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, secondQuantity.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = (T)(object)(un.GetUnitOverflow() * ((double)(object)qresult.Value)); } } } else { qresult.Value = MultiplyGenericByGeneric(firstQuantity.Value, secondQuantity.Value); //check if any of the two quantities have a valid unit // to be able to derive the current quantity if (firstQuantity.Unit != null && secondQuantity.Unit != null) { Unit un = new Unit(qresult.GetType(), firstQuantity.Unit, secondQuantity.Unit); qresult.Unit = un; if (un.IsOverflowed) { qresult.Value = MultiplyScalarByGeneric(un.GetUnitOverflow(), qresult.Value); } } } return(qresult); }
/// <summary> /// Parse the input name and return the quantity object from it. /// </summary> /// <typeparam name="T">container type of the value</typeparam> /// <param name="quantityName"></param> /// <returns></returns> public static AnyQuantity <T> Parse(string quantityName) { Type QuantityType = QuantityDimension.QuantityTypeFrom(quantityName); if (QuantityType == null) { throw new QuantityNotFoundException(); } else { //QuantityType = QuantityType.MakeGenericType(typeof(T)); //AnyQuantity<T> qty = (AnyQuantity<T>)Activator.CreateInstance(QuantityType); AnyQuantity <T> qty = QuantityDimension.QuantityFrom <T>(QuantityDimension.DimensionFrom(QuantityType)); return(qty); } }
public static AnyQuantity <T> Subtract(AnyQuantity <T> firstQuantity, AnyQuantity <T> secondQuantity) { if (firstQuantity.Equals(secondQuantity)) { AnyQuantity <T> AQ = null; try { AQ = QuantityDimension.QuantityFrom <T>(firstQuantity.Dimension); //exception happen when adding two derived quantities together } catch (QuantityNotFoundException) { //keep the first quantity configuration. AQ = (AnyQuantity <T>)firstQuantity.Clone(); } if (typeof(T) == typeof(decimal) || typeof(T) == typeof(double) || typeof(T) == typeof(float) || typeof(T) == typeof(int) || typeof(T) == typeof(short)) { //use direct calculations double firstVal = (double)(object)firstQuantity.Value; double secondVal = (double)(object)secondQuantity.Value; //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = stof.ConversionFactor * secondVal; } ////sum the values double result = firstVal - secondVal; if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //assign the unit of first quantity to the result. AQ.Unit = (Unit)firstQuantity.Unit.Clone(); } AQ.Value = (T)(object)result; return(AQ); } else { T firstVal = (firstQuantity.Value); T secondVal = (secondQuantity.Value); //correct the values according to left unit or first unit. //the resulted quantity has the values of the first unit. if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //factor from second unit to first unit UnitPathStack stof = secondQuantity.Unit.PathToUnit(firstQuantity.Unit); secondVal = MultiplyScalarByGeneric(stof.ConversionFactor, secondVal); } var expr = Expression.Subtract(Expression.Constant(firstVal), Expression.Constant(secondVal)); // Construct Lambda function which return one object. Expression <Func <T> > cq = Expression.Lambda <Func <T> >(expr); // compile the function Func <T> aqf = cq.Compile(); // execute the function T result = aqf(); if (firstQuantity.Unit != null && secondQuantity.Unit != null) { //assign the unit of first quantity to the result. AQ.Unit = firstQuantity.Unit; } AQ.Value = result; return(AQ); } } else { throw new QuantitiesNotDimensionallyEqualException(); } }