예제 #1
0
 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);
 }
예제 #2
0
 public Combinator(IEnumerable <ExponentMeasureUnit> units)
 {
     _normM = new List <AtomicMeasureUnit>();
     _normE = new List <int>();
     _dimensionLessFactor = ExpFactor.Neutral;
     if (units != null)
     {
         Add(units);
     }
 }
예제 #3
0
        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);
        }
예제 #4
0
 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}'.");
                }
            }));
        }
예제 #6
0
 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);
     }
 }
예제 #7
0
        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);
        }
예제 #8
0
 /// <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)
 {
 }
예제 #9
0
 /// <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;
 }
예제 #10
0
 /// <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);
 }
예제 #11
0
 /// <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);
예제 #12
0
        /// <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));
        }