Formatting numbers with significant figures in C#

后端 未结 8 1398
小鲜肉
小鲜肉 2020-11-28 13:01

I have some decimal data that I am pushing into a SharePoint list where it is to be viewed. I\'d like to restrict the number of significant figures displayed in the result

相关标签:
8条回答
  • 2020-11-28 13:56

    I found this article doing a quick search on it. Basically this one converts to a string and goes by the characters in that array one at a time, till it reached the max. significance. Will this work?

    0 讨论(0)
  • 2020-11-28 14:07

    I have a shorted answer to calculating significant figures of a number. Here is the code & the test results...

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApplicationRound
    {
        class Program
        {
            static void Main(string[] args)
            {
                //char cDecimal = '.';    // for English cultures
                char cDecimal = ',';    // for German cultures
                List<double> l_dValue = new List<double>();
                ushort usSignificants = 5;
    
                l_dValue.Add(0);
                l_dValue.Add(0.000640589);
                l_dValue.Add(-0.000640589);
                l_dValue.Add(-123.405009);
                l_dValue.Add(123.405009);
                l_dValue.Add(-540);
                l_dValue.Add(540);
                l_dValue.Add(-540911);
                l_dValue.Add(540911);
                l_dValue.Add(-118.2);
                l_dValue.Add(118.2);
                l_dValue.Add(-118.18);
                l_dValue.Add(118.18);
                l_dValue.Add(-118.188);
                l_dValue.Add(118.188);
    
                foreach (double d in l_dValue)
                {
                    Console.WriteLine("d = Maths.Round('" +
                        cDecimal + "', " + d + ", " + usSignificants +
                        ") = " + Maths.Round(
                        cDecimal, d, usSignificants));
                }
    
                Console.Read();
            }
        }
    }
    

    The Maths class used is as follows:

    using System;
    using System.Text;
    
    namespace ConsoleApplicationRound
    {
        class Maths
        {
            /// <summary>
            ///     The word "Window"
            /// </summary>
            private static String m_strZeros = "000000000000000000000000000000000";
            /// <summary>
            ///     The minus sign
            /// </summary>
            public const char m_cDASH = '-';
    
            /// <summary>
            ///     Determines the number of digits before the decimal point
            /// </summary>
            /// <param name="cDecimal">
            ///     Language-specific decimal separator
            /// </param>
            /// <param name="strValue">
            ///     Value to be scrutinised
            /// </param>
            /// <returns>
            ///     Nr. of digits before the decimal point
            /// </returns>
            private static ushort NrOfDigitsBeforeDecimal(char cDecimal, String strValue)
            {
                short sDecimalPosition = (short)strValue.IndexOf(cDecimal);
                ushort usSignificantDigits = 0;
    
                if (sDecimalPosition >= 0)
                {
                    strValue = strValue.Substring(0, sDecimalPosition + 1);
                }
    
                for (ushort us = 0; us < strValue.Length; us++)
                {
                    if (strValue[us] != m_cDASH) usSignificantDigits++;
    
                    if (strValue[us] == cDecimal)
                    {
                        usSignificantDigits--;
                        break;
                    }
                }
    
                return usSignificantDigits;
            }
    
            /// <summary>
            ///     Rounds to a fixed number of significant digits
            /// </summary>
            /// <param name="d">
            ///     Number to be rounded
            /// </param>
            /// <param name="usSignificants">
            ///     Requested significant digits
            /// </param>
            /// <returns>
            ///     The rounded number
            /// </returns>
            public static String Round(char cDecimal,
                double d,
                ushort usSignificants)
            {
                StringBuilder value = new StringBuilder(Convert.ToString(d));
    
                short sDecimalPosition = (short)value.ToString().IndexOf(cDecimal);
                ushort usAfterDecimal = 0;
                ushort usDigitsBeforeDecimalPoint =
                    NrOfDigitsBeforeDecimal(cDecimal, value.ToString());
    
                if (usDigitsBeforeDecimalPoint == 1)
                {
                    usAfterDecimal = (d == 0)
                        ? usSignificants
                        : (ushort)(value.Length - sDecimalPosition - 2);
                }
                else
                {
                    if (usSignificants >= usDigitsBeforeDecimalPoint)
                    {
                        usAfterDecimal =
                            (ushort)(usSignificants - usDigitsBeforeDecimalPoint);
                    }
                    else
                    {
                        double dPower = Math.Pow(10,
                            usDigitsBeforeDecimalPoint - usSignificants);
    
                        d = dPower*(long)(d/dPower);
                    }
                }
    
                double dRounded = Math.Round(d, usAfterDecimal);
                StringBuilder result = new StringBuilder();
    
                result.Append(dRounded);
                ushort usDigits = (ushort)result.ToString().Replace(
                    Convert.ToString(cDecimal), "").Replace(
                    Convert.ToString(m_cDASH), "").Length;
    
                // Add lagging zeros, if necessary:
                if (usDigits < usSignificants)
                {
                    if (usAfterDecimal != 0)
                    {
                        if (result.ToString().IndexOf(cDecimal) == -1)
                        {
                            result.Append(cDecimal);
                        }
    
                        int i = (d == 0) ? 0 : Math.Min(0, usDigits - usSignificants);
    
                        result.Append(m_strZeros.Substring(0, usAfterDecimal + i));
                    }
                }
    
                return result.ToString();
            }
        }
    }
    

    Any answer with a shorter code?

    0 讨论(0)
提交回复
热议问题