public Unit RaiseUnitPower(float power) { //make short-cut when power equal zero return dimensionless unit immediatly // because if I left the execution to the end // the dimensionless unit is created and wrapping the original unit under sub unit // and this made errors in conversion between dimensionless units :). if (power == 0) { return(Unit.DiscoverUnit(QuantityDimension.Dimensionless)); } Unit u = (Unit)this.MemberwiseClone(); if (SubUnits != null) { u.SubUnits = new List <Unit>(SubUnits.Count); for (int i = 0; i < SubUnits.Count; i++) { u.SubUnits.Add(SubUnits[i].RaiseUnitPower(power)); } } else { u.unitExponent *= power; //the exponent is changing in strongly typed units } u._UnitDimension = this._UnitDimension * power; //must change the unit dimension of the unit // however because the unit is having sub units we don't have to modify the exponent of it // note: unit that depend on sub units is completly unaware of its exponent // or I should say it is always equal = 1 u._QuantityType = QuantityDimension.GetQuantityTypeFrom(u._UnitDimension); if (u.SubUnits == null && u.unitExponent == 1) { //no sub units and exponent ==1 then no need to processing return(u); } else if (u.SubUnits == null) { //exponent != 1 like ^5 ^0.3 we need processing return(new Unit(u._QuantityType, u)); } else { //consist of sub units definitly we need processing. return(new Unit(u._QuantityType, u.SubUnits.ToArray())); } }
/// <summary> /// Resturns the name of the quantity associated with this dimension /// </summary> /// <param name="dimension"></param> /// <returns></returns> public static QsValue FromDimension(QsParameter dimension) { string ss = dimension.ParameterRawText; if (dimension.QsNativeValue is QsText) { ss = ((QsText)dimension.QsNativeValue).Text; } var q = QuantityDimension.Parse(ss); string qt = QuantityDimension.GetQuantityTypeFrom(q).Name; return(new QsText(qt.Substring(0, qt.Length - 2))); }
/// <summary> /// Returns the unit corresponding to the passed string. /// Suppors units with exponent. /// </summary> /// <param name="unit"></param> /// <returns></returns> internal static Unit ParseUnit(string un) { if (un == "1") { //this is dimensionless value return(new Unit(typeof(Quantities.DimensionlessQuantities.DimensionlessQuantity <>))); } //find '^' string[] upower = un.Split('^'); string unit = upower[0]; int power = 1; if (upower.Length > 1) { power = int.Parse(upower[1], CultureInfo.InvariantCulture); } Unit FinalUnit = null; //Phase 1: try direct mapping. try { FinalUnit = FindUnit(unit); } catch (UnitNotFoundException) { //try to find if it as a Metric unit with prefix //loop through all prefixes. for (int i = 10; i >= -10; i -= 1) { if (i == 0) { i--; //skip the None prefix } if (unit.StartsWith(MetricPrefix.GetPrefix(i).Symbol, StringComparison.Ordinal)) { //found MetricPrefix mp = MetricPrefix.GetPrefix(i); string upart = unit.Substring(mp.Symbol.Length); //then it should be MetricUnit otherwise die :) MetricUnit u = FindUnit(upart) as MetricUnit; if (u == null) { goto nounit; } u.UnitPrefix = mp; FinalUnit = u; break; } } } if (FinalUnit == null) { goto nounit; } if (power > 1) { //discover the new type QuantityDimension ud = FinalUnit.UnitDimension * power; Unit[] chobits = new Unit[power]; //what is chobits any way :O for (int iy = 0; iy < power; iy++) { chobits[iy] = (Unit)FinalUnit.MemberwiseClone(); } Type uQType = null; uQType = QuantityDimension.GetQuantityTypeFrom(ud); FinalUnit = new Unit(uQType, chobits); } return(FinalUnit); nounit: throw new UnitNotFoundException(un); }
/// <summary> /// Parse units with exponent and one division '/' with many '.' /// i.e. m/s m/s^2 kg.m/s^2 /// </summary> /// <param name="units"></param> /// <returns></returns> public static Unit Parse(string units) { // if found treat store its value. // m/s^2 m.K/m.s // kg^2/in^2.s // sea //search for '/' string[] uny = units.Split('/'); string[] numa = uny[0].Split('.'); List <Unit> dunits = new List <Unit>(); foreach (string num in numa) { dunits.Add(ParseUnit(num)); } if (uny.Length > 1) { string[] dena = uny[1].Split('.'); foreach (string den in dena) { var uu = ParseUnit(den); if (uu.SubUnits != null) { //then it is unit with sub units in it if (uu.SubUnits.Count == 1) { uu = uu.SubUnits[0]; } } dunits.Add(uu.Invert()); } } if (dunits.Count == 1) { return(dunits[0]); } //get the dimension of all units QuantityDimension ud = QuantityDimension.Dimensionless; foreach (Unit un in dunits) { ud += un.UnitDimension; } Type uQType = null; uQType = QuantityDimension.GetQuantityTypeFrom(ud); Unit FinalUnit = new Unit(uQType, dunits.ToArray()); return(FinalUnit); }