0

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

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

我不喜欢所有这些与字符串的转换,并且不禁想到必须有一个更有效的解决方案?

4

1 回答 1

1

查看这个问题的公认答案。

我已将代码从接受的答案移植到 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显示了格式化数字的更有效方式。

于 2013-09-11T14:07:36.610 回答