/// <summary>
        /// SetValueScaled: change value from another ScaledType value, check for convertability of scales.
        /// </summary>
        /// <param name="value">New value (possibly in different scale)</param>
        /// <param name="copy">Action to be done by the child to get the correct value.</param>
        /// <returns>True if scales were convertable and a new value is set.</returns>
        /// <remarks>
        /// A value in DoubleST is required for scaling.
        /// Scaling is done with factors and these are (by design) doubles.
        /// </remarks>
        protected bool SetValueScaled(DoubleST value, Action <DoubleST> copy)
        {
            if (Scale == value.Scale)
            {
                copy(null);
                return(true);
            }

            var v1b = BaseFactor();
            var v2b = value.BaseFactor();

            if (v1b.Scale == v2b.Scale)
            {
                var v1n = BaseNormal();
                var v2n = value.BaseNormal();
                // var v2 = value * v1n / v2n
                copy(value * v1n / v2n);
                return(true);

                // extra check:
                //var result = (scale == v2.scale);
                //if (result) Value = v2.Value;
                //return result;
            }
            return(false);
        }
Exemple #2
0
        /// <summary>
        /// Mul operator *: Multiply two values.
        /// </summary>
        /// <param name="left">A value to multiply with</param>
        /// <param name="right">A value to multiply</param>
        /// <returns>(left.value * right.value, [Normalised(left.scale right.scale)])</returns>
        public static DoubleST Mul(DoubleST left, DoubleST right)
        {
            var result = new DoubleST(left.Value * right.Value, left.Scale);

            result.Append(right.Scale);
            return(result);
        }
Exemple #3
0
 /// <summary>
 /// Assign: assign a new value to this instance
 /// </summary>
 /// <param name="value">The new value</param>
 /// <exception cref="ArgumentOutOfRangeException">Scales of this and the other must be (syntactical) equivalents</exception>
 /// <remarks>It is not possible to override operator=()</remarks>
 public void Assign(DoubleST other)
 {
     if (ReferenceEquals(this, other))
     {
         return;
     }
     base.Assign(other);
     Value = other.Value;
 }
Exemple #4
0
 /// <summary>
 /// Sub operator -: Subtract two values with equal scale.
 /// </summary>
 /// <param name="left">A value to subtract from</param>
 /// <param name="right">A value to subtract</param>
 /// <exception cref="ArgumentOutOfRangeException">left scale is not (semantical) equal to right scale.</exception>
 /// <returns>(left.value - right.value, [scale])</returns>
 public static DoubleST Sub(DoubleST left, DoubleST right)
 {
     if (left.Scale != right.Scale)
     {
         var msg = $"DoubleST: operation not supported: {left.Scale} - {right.Scale}";
         //log.Debug(msg);
         throw new ArgumentOutOfRangeException(msg);
     }
     return(new DoubleST(left.Value - right.Value, left.Scale));
 }
        /// <summary>
        /// BaseFactor: expressing the ScaleType (1, [target]) in basic Units of the ScaleType
        /// </summary>
        /// <remarks>
        /// Example: ScaleType (1, [cm])
        ///    The BaseUnit for [cm] is Unit.Base, the meter [m]
        ///    BaseNormal = (0.01, [m]), (1, [cm]) = (0.01, [m])
        ///
        /// This value is usefull for checking if a conversion is possible from one value
        /// to another. Both value BaseFactors must have identical scales.
        ///
        /// Pitfall: Do not use for conversion!
        /// e.g.:
        ///    (C1, [m]) = (1, [ft]) = BaseFactor([ft])
        ///    (C2, [m]) = (1, [cm]) = BaseFactor([cm])
        ///    then
        ///    (y, [ft]) = (x, [cm])*(C2, [m])/(C1, [m])
        ///              = (x*C2/C1, [cm])
        ///              The value appears to be correct but the scale is incorrect.
        ///
        /// Note: The relation between
        ///       (c1, [Unit.Base]) = BaseNormal([Unit]) and
        ///       (C1, [Unit]) = BaseFactor([Unit])
        ///       is c1 = 1/C1
        /// </remarks>
        /// <seealso cref="BaseNormal"/>
        /// <param name="target">A list of ScaledUnit instances that form the scale to use.</param>
        /// <returns>
        /// (x, [Unit.Base]), the conversion of (1, [Unit]) where Unit.Base is in { [m], [g], [s],... }
        /// </returns>
        static DoubleST BaseFactor(Scale target)
        {
            var result = new DoubleST(1.0);

            foreach (var s in target)
            {
                result.Append(s.Unit.Base(), s.Exp);
                result = result / s.Factor();
            }
            return(result);
        }
Exemple #6
0
        /// <summary>
        /// Div operator /: Divide two values.
        /// </summary>
        /// <param name="left">A value to divide to</param>
        /// <param name="right">A value to divide with</param>
        /// <returns>(left.value / right.value, [Normalised(left.scale, right.scale^-1)])</returns>
        public static DoubleST Div(DoubleST left, DoubleST right)
        {
            if (right.Value == 0.0)
            {
                throw new DivideByZeroException($"{left} / {right} ");
            }
            var result = new DoubleST(left.Value / right.Value, left.Scale);

            result.Append(right.Scale, reciproce: true);
            return(result);
        }
Exemple #7
0
 /// <summary>
 /// .ctor: copy constructor.
 /// </summary>
 /// <param name="other">Data to copy.</param>
 public DoubleST(DoubleST other) : base(other.Scale)
 {
     Value = other.value;
 }