根据所需的小数位数*和* sig figs格式化数字

时间:2013-09-11 12:24:49

标签: c#

我们的科学应用程序允许用户配置显示数值时要使用的有效数字小数位数。目前正在使用此代码完成格式化: -

var sigFigFormatted = valueToConvert.ToString("G" + numberOfSigFigs);
var theFullyFormattedValue = Convert.ToDouble(sigFigFormatted)
                                 .ToString("F" + numberOfDecimalPlaces);

我不喜欢所有这些对字符串的转换,并且不禁认为必须有更高效的解决方案吗?

1 个答案:

答案 0 :(得分:1)

查看this question的已接受答案。

我已将接受的答案中的代码移植到C#并进行了一些测试。 代码:

using System;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApplication1
{
    public static class NumericExtensions
    {
        public static double RoundToSignificantFigures(this double num, int n)
        {
            if (num == 0)
            {
                return 0;
            }

            double magnitude = Math.Pow(10, n - (int)Math.Ceiling(Math.Log10(Math.Abs(num))));
            double shifted = Math.Round(num * magnitude);
            return shifted / magnitude;
        }

        public static double RoundToSignificantFiguresWithConvert(this double num, int n)
        {
            var sigFigFormatted = num.ToString("G" + n.ToString());
            return Convert.ToDouble(sigFigFormatted);
        }
    }

    class Program
    {
        static string[] Test1(double[] numbers, int numberOfSigFigs, int numberOfDecimalPlaces)
        {
            var result = new string[numbers.Length];
            for (int i = 0; i < numbers.Length; i++)
            {
                result[i] = numbers[i].RoundToSignificantFigures(numberOfSigFigs).ToString("F" + numberOfDecimalPlaces.ToString());
            }
            return result;
        }

        static string[] Test2(double[] numbers, int numberOfSigFigs, int numberOfDecimalPlaces)
        {
            var result = new string[numbers.Length];
            for (int i = 0; i < numbers.Length; i++)
            {
                result[i] = numbers[i].RoundToSignificantFiguresWithConvert(numberOfSigFigs).ToString("F" + numberOfDecimalPlaces.ToString());
            }
            return result;
        }

        static void Main(string[] args)
        {
            // create an array or random numbers 
            var rng = new Random();
            var numbers = new double[100000];
            for (int i = 0; i < numbers.Length; i++)
            {
                numbers[i] = 10000000000000000000D * (rng.NextDouble() - 0.5D);
            }

            const int numberOfSigFigs = 3;
            const int numberOfDecimalPlaces = 3;

            // make first run without time measurement
            Test1(numbers, numberOfSigFigs, numberOfDecimalPlaces);
            Test2(numbers, numberOfSigFigs, numberOfDecimalPlaces);

            const int numberOfIterations = 100;
            var sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < numberOfIterations; i++)
            {
                Test1(numbers, numberOfSigFigs, numberOfDecimalPlaces);
            }
            sw.Stop();
            Console.WriteLine("Test1 elapsed {0} ms", sw.ElapsedMilliseconds.ToString());

            sw.Restart();
            for (int i = 0; i < numberOfIterations; i++)
            {
                Test2(numbers, numberOfSigFigs, numberOfDecimalPlaces);
            }
            sw.Stop();
            Console.WriteLine("Test2 elapsed {0} ms", sw.ElapsedMilliseconds.ToString());

            Console.ReadKey();
        }

    }

}

结果:

Test1 elapsed 7259 ms
Test2 elapsed 12918 ms

所以NumericExtensions.RoundToSignificantFigures显示了更有效的数字格式化方法。