예제 #1
0
        /// <summary>Formats the value into a human friendly string with a unit specification.</summary>
        /// <remarks>
        /// The method tries to keep the resulted string meaningful and as short as possible. For this
        /// reason the big values may be scaled down and/or rounded.
        /// </remarks>
        /// <param name="value">The unscaled numeric value to format.</param>
        /// <param name="scale">
        /// The fixed scale to apply to the value before formatting. The formatting method can uderstand
        /// only a few scales:
        /// <list type="bullet">
        /// <item>Tons: scale=<c>1.0</c>. <i>It's a base mass unit in the game.</i></item>
        /// <item>Kilograms: scale=<c>1.0e-3</c>.</item>
        /// <item>Grams: scale=<c>1.0e-6</c>.</item>
        /// </list>
        /// <para>
        /// The unknown scales will be rounded <i>up</i> to the closest known scale. If this parameter
        /// is omitted, then the best scale for the value will be choosen automatically.
        /// </para>
        /// </param>
        /// <param name="format">
        /// The specific numeric number format to use. If this parameter is specified, then the method
        /// doesn't try to guess the right scale. Instead, it uses either the provided
        /// <paramref name="scale"/>, or <c>1.0</c> if nothing is provided. If the format is not
        /// specified, then it's choosen basing on the scale.
        /// </param>
        /// <returns>A formatted and localized string</returns>
        /// <example><code source="Examples/GUIUtils/TypeFormatters/MassType-Examples.cs" region="MassTypeDemo2_FormatDefault"/></example>
        /// <example><code source="Examples/GUIUtils/TypeFormatters/MassType-Examples.cs" region="MassTypeDemo2_FormatWithScale"/></example>
        /// <example><code source="Examples/GUIUtils/TypeFormatters/MassType-Examples.cs" region="MassTypeDemo2_FormatFixed"/></example>
        public static string Format(double value, double?scale = null, string format = null)
        {
            // Detect the scale, and scale the value.
            string units;
            double scaledValue;

            if (format != null && !scale.HasValue)
            {
                scale = 1.0; // No scale detection.
            }
            var testValue = Math.Abs(value);

            if (!scale.HasValue)
            {
                // Auto detect the best scale.
                if (testValue < 0.001)
                {
                    scale = 0.000001;
                }
                else if (testValue < 1.0)
                {
                    scale = 0.001;
                }
                else
                {
                    scale = 1.0;
                }
            }
            if (value < double.Epsilon)
            {
                scaledValue = 0;
                units       = ""; // Zero value has no units - it's ZERO.
            }
            else if (scale <= 0.000001)
            {
                scaledValue = value / 0.000001;
                units       = gram;
            }
            else if (scale <= 0.001)
            {
                scaledValue = value / 0.001;
                units       = kilogram;
            }
            else
            {
                scaledValue = value;
                units       = ton;
            }
            if (format != null)
            {
                return(scaledValue.ToString(format) + units);
            }
            return(CompactNumberType.Format(scaledValue) + units);
        }
예제 #2
0
        /// <summary>Formats the value into a human friendly string with a unit specification.</summary>
        /// <remarks>
        /// <para>
        /// The method tries to keep the resulted string meaningful and as short as possible. For this
        /// reason the big values may be scaled down and/or rounded.
        /// </para>
        /// <para>
        /// The base velocity unit in the game is <i>m/s</i>. I.e. value <c>1.0</c> in the game
        /// units is <i>one meter per second</i>. Keep it in mind when passing the argument.
        /// </para>
        /// </remarks>
        /// <param name="value">The unscaled numeric value to format.</param>
        /// <param name="scale">
        /// The fixed scale to apply to the value before formatting. The formatting method can uderstand
        /// only a few scales:
        /// <list type="bullet">
        /// <item>m/s: scale=<c>1.0</c>. <i>It's a base velocity unit in the game.</i></item>
        /// <item>km/s: scale=<c>1.0e+3</c>.</item>
        /// <item>Mm/s: scale=<c>1.0e+6</c>.</item>
        /// </list>
        /// <para>
        /// The unknown scales will be rounded <i>up</i> to the closest known scale. If this parameter
        /// is omitted, then the best scale for the value will be choosen automatically.
        /// </para>
        /// </param>
        /// <param name="format">
        /// The specific numeric number format to use. If this parameter is specified, then the method
        /// doesn't try to guess the right scale. Instead, it uses either the provided
        /// <paramref name="scale"/>, or <c>1.0</c> if nothing is provided. If the format is not
        /// specified, then it's choosen basing on the scale.
        /// </param>
        /// <returns>A formatted and localized string</returns>
        /// <example><code source="Examples/GUIUtils/TypeFormatters/VelocityType-Examples.cs" region="VelocityTypeDemo2_FormatDefault"/></example>
        /// <example><code source="Examples/GUIUtils/TypeFormatters/VelocityType-Examples.cs" region="VelocityTypeDemo2_FormatFixed"/></example>
        public static string Format(double value, double?scale = null, string format = null)
        {
            // Detect the scale, and scale the value.
            string units;
            double scaledValue;

            if (format != null && !scale.HasValue)
            {
                scale = 1.0; // No scale detection.
            }
            var testValue = Math.Abs(value);

            if (!scale.HasValue)
            {
                // Auto detect the best scale.
                if (testValue >= 1.0e+6)
                {
                    scale = 1.0e+6;
                }
                else if (testValue >= 1.0e+3)
                {
                    scale = 1.0e+3;
                }
                else
                {
                    scale = 1.0;
                }
            }
            if (scale >= 1.0e+6)
            {
                scaledValue = value / 1.0e+6;
                units       = megameterPerSecond;
            }
            else if (scale >= 1.0e+3)
            {
                scaledValue = value / 1.0e+3;
                units       = kilometerPerSecond;
            }
            else
            {
                scaledValue = value;
                units       = meterPerSecond;
            }
            if (format != null)
            {
                return(scaledValue.ToString(format) + units);
            }
            return(CompactNumberType.Format(scaledValue) + units);
        }