/// <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); }
/// <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); }