MeasureStandardPrefix(string abbreviation, string name, int eBase, int exp) { Abbreviation = abbreviation; Name = name; Base = eBase; Exponent = exp; Factor = eBase == 2 ? new ExpFactor(exp, 0) : new ExpFactor(0, exp); }
public Combinator(IEnumerable <ExponentMeasureUnit> units) { _normM = new List <AtomicMeasureUnit>(); _normE = new List <int>(); _dimensionLessFactor = ExpFactor.Neutral; if (units != null) { Add(units); } }
ExponentMeasureUnit CreateExponentPrefixed(int exp, ExpFactor adjustment, AtomicMeasureUnit atomic) { ExponentMeasureUnit u; if (!adjustment.IsNeutral) { var best = MeasureStandardPrefix.FindBest(adjustment, atomic.AutoStandardPrefix); atomic = RegisterPrefixed(best.Adjustment, best.Prefix, atomic); } u = RegisterExponent(exp, atomic); return(u); }
ExpFactor ParseFactor(string s, ExpFactor f) { if (s[0] == '2') { f = f.Multiply(new ExpFactor(Int16.Parse(s.Substring(2)), 0)); } else { f = f.Multiply(new ExpFactor(0, Int16.Parse(s.Substring(3)))); } return(f); }
/// <summary> /// The isNormalized is nullable: when automatically creating PrefixedUnit this is null and: /// - if the unit must be created it won't be the normalized one. /// - if the unit is found, we don't check the potential race condition. /// Only when explicitly registering/creating the unit with true or false, the resulting unit IsNormalized /// property is checked to prevent race conditions. /// </summary> internal PrefixedMeasureUnit RegisterPrefixed(ExpFactor adjustment, MeasureStandardPrefix p, AtomicMeasureUnit u, bool?isNormalized = null) { var names = PrefixedMeasureUnit.ComputeNames(adjustment, p, u); return(Register(names.A, names.N, () => new PrefixedMeasureUnit(this, names, adjustment, p, u, isNormalized ?? false), m => { if (isNormalized.HasValue && m.IsNormalized != isNormalized) { ThrowArgumentException(m, $"new IsNormalized '{isNormalized}' differ from '{m.IsNormalized}'."); } })); }
public void Add(AtomicMeasureUnit u, int exp) { if (u.AtomicMeasureUnit.Normalization == None) { var fp = u.AtomicMeasureUnit.NormalizationFactor.ExpFactor.Power(exp); _dimensionLessFactor = _dimensionLessFactor.Multiply(fp); } else { for (int i = 0; i < _normM.Count; ++i) { if (_normM[i] == u) { _normE[i] += exp; return; } } _normM.Add(u); _normE.Add(exp); } }
bool TryParseExponent(Match match, out ExponentMeasureUnit u, bool skipFirstLookup = false) { if (!skipFirstLookup && TryGetExistingExponent(match.ToString(), out u)) { return(true); } u = null; // Handling dimensionless unit. var factor = match.Groups[4].Value; if (factor.Length > 0) { var f = ParseFactor(factor, ExpFactor.Neutral); u = RegisterPrefixed(f, MeasureStandardPrefix.None, MeasureUnit.None); return(true); } string sExp = match.Groups[3].Value; int exp = sExp.Length > 0 ? Int32.Parse(sExp) : 1; if (exp == 0) { u = MeasureUnit.None; return(true); } string withoutExp = match.Groups[1].Value + match.Groups[2].Value; if (_allUnits.TryGetValue(withoutExp, out var unit)) { if (exp == 1 && unit is ExponentMeasureUnit direct) { u = direct; return(true); } if (!(unit is AtomicMeasureUnit atomic)) { return(false); } u = RegisterExponent(exp, atomic); return(true); } ExpFactor adjustment = ExpFactor.Neutral; foreach (Capture f in match.Groups[1].Captures) { adjustment = ParseFactor(f.Value, adjustment); } string withoutAdjustment = match.Groups[2].Value; if (_allUnits.TryGetValue(withoutAdjustment, out unit)) { if (!(unit is AtomicMeasureUnit basic)) { return(false); } if (basic is PrefixedMeasureUnit prefix) { adjustment = adjustment.Multiply(prefix.AdjustmentFactor).Multiply(prefix.Prefix.Factor); basic = prefix.AtomicMeasureUnit; } u = CreateExponentPrefixed(exp, adjustment, basic); return(true); } var p = MeasureStandardPrefix.FindPrefix(withoutAdjustment); if (p == MeasureStandardPrefix.None) { return(false); } withoutAdjustment = withoutAdjustment.Substring(p.Abbreviation.Length); if (withoutAdjustment.Length == 0) { return(false); } if (_allUnits.TryGetValue(withoutAdjustment, out unit)) { if (!(unit is AtomicMeasureUnit basic)) { return(false); } if (basic is PrefixedMeasureUnit prefix) { return(false); } adjustment = adjustment.Multiply(p.Factor); u = CreateExponentPrefixed(exp, adjustment, basic); return(true); } return(false); }
/// <summary> /// Initializes a new <see cref="FullFactor"/> with a <see cref="Factor"/> = 1.0. /// </summary> /// <param name="f">The exponent factor.</param> public FullFactor(ExpFactor f) : this(1.0, f) { }
/// <summary> /// Initializes a new <see cref="FullFactor"/>. /// </summary> /// <param name="f">The factor.</param> /// <param name="e">The exponent factor.</param> public FullFactor(double f, ExpFactor e) { Factor = f; ExpFactor = e; }
/// <summary> /// Finds the best prefix given a <see cref="ExpFactor"/>. /// If both metric and binary exponents exist (ie. are not zero), the metric prefix /// is selected (the Exp2 is injected in the adjustment factor). /// </summary> /// <param name="newExp">Must not be the neutral factor.</param> /// <param name="stdPrefix"> /// Whether the actual standard prefixes are allowed. When not, it is the adjustemnt factor /// that handles the exponent and the prefix None is used. /// </param> /// <returns>The best prefix with the required adjustment factor.</returns> internal static (ExpFactor Adjustment, MeasureStandardPrefix Prefix) FindBest(ExpFactor newExp, AutoStandardPrefix stdPrefix) { // Privilegiates metric prefix if any and if metric is allowed. Debug.Assert(!newExp.IsNeutral); if (newExp.Exp10 != 0 && (stdPrefix & AutoStandardPrefix.Metric) != 0) { var b10 = FindBest(newExp.Exp10, _allMetricIndex, _allMetric); return(new ExpFactor(newExp.Exp2, b10.Item1), b10.Item2); } if (newExp.Exp2 != 0 && (stdPrefix & AutoStandardPrefix.Binary) != 0) { Debug.Assert(newExp.Exp2 != 0); var b2 = FindBest(newExp.Exp2, _allBinaryIndex, _allBinary); return(new ExpFactor(b2.Item1, 0), b2.Item2); } return(newExp, None); }
/// <summary> /// <see cref="Factor"/> must be 1.0 and then <see cref="ExpFactor"/> must be equal to <paramref name="other"/>. /// </summary> /// <param name="other">The other factor.</param> /// <returns>True if factor is 1.0 ExpFactor equals other. False otherwise.</returns> public bool Equals(ExpFactor other) => Factor == 1.0 && ExpFactor.Equals(other);
/// <summary> /// The isNormalized is nullable: when automatically creating PrefixedUnit this is null and : /// - if the unit must be created it won't be the normalized one. /// - if the unit is found, we don't check the potential race condition. /// Only when explicitly registering/creating the unit with true or false, the resulting unit IsNormalized /// property is checked to prevent race conditions. /// </summary> internal PrefixedMeasureUnit RegisterPrefixed(ExpFactor adjustment, MeasureStandardPrefix p, AtomicMeasureUnit u, bool?isNormalized = null) { var names = PrefixedMeasureUnit.ComputeNames(adjustment, p, u); return(Register(names.A, names.N, () => new PrefixedMeasureUnit(this, names, adjustment, p, u, isNormalized ?? false), m => !isNormalized.HasValue || m.IsNormalized == isNormalized)); }