怎样避免C#中将小数转换为字符串时出现科学记数法

在C#中如果float、double、decimal类型的值,小数点后的位数太多时,C#会用科学记数法来表示小数的值。

例如下面的double类型0.00009,如果我们直接将其用ToString()方法转换为字符串,就会变为科学记数法9E-05(目前来看只有整数位为0的小数会有科学记数法的问题,例如1.00009不会被ToString()方法转换为科学记数法)

double number = 0.00009;
string defaultNumber = number.ToString(); //9E-05

所以我们可以通过显示声明转换后字符串的格式,避免在C#中出现科学记数法:

using System;

namespace NetCoreFloat
{
    class Program
    {
        static void Main(string[] args)
        {
            double number = 0.00009;
            string defaultNumber = number.ToString(); //9E-05

            string numberFromToString = number.ToString("N5"); //0.00009

            string numberFromStringFormat = string.Format("{0:F5}", number); //0.00009

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

虽然上面的代码可以让小数转换为字符串后不是科学记数法,但是很明显我们需要准确地知道小数点后会有多少位小数,才能保证转换后的精度不会丢失。

如果我们将转换格式的精度设置得过小,就会造成精度损失,如下所示:

using System;

namespace NetCoreFloat
{
    class Program
    {
        static void Main(string[] args)
        {
            double number = 0.00009;
            string defaultNumber = number.ToString(); //9E-05

            string numberFromToString = number.ToString("N3"); //0.000

            string numberFromStringFormat = string.Format("{0:F3}", number); //0.000

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

而如果我们将转换格式的精度设置得过大,又会在小数最后产生多余的0,如下所示:

using System;

namespace NetCoreFloat
{
    class Program
    {
        static void Main(string[] args)
        {
            double number = 0.00009;
            string defaultNumber = number.ToString(); //9E-05

            string numberFromToString = number.ToString("N10"); //0.0000900000

            string numberFromStringFormat = string.Format("{0:F10}", number); //0.0000900000

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

对此我们需要在转换格式中使用#字符,#字符不会在小数最后产生多余的0,如下所示:

扫描二维码关注公众号,回复: 6293489 查看本文章
using System;

namespace NetCoreFloat
{
    class Program
    {
        static void Main(string[] args)
        {
            double number = 0.00009;

            string numberFromToString = number.ToString("0.#####"); //0.00009
            numberFromToString = number.ToString("0.##########"); //0.00009

            number = 100.00009;
            numberFromToString = number.ToString("0.#####"); //100.00009
            numberFromToString = number.ToString("0.##########"); //100.00009

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

实际上我们可以最大声明339个#字符,这样可以保证所有小数都能被正确地转换为字符串:

using System;

namespace NetCoreFloat
{
    class Program
    {
        static void Main(string[] args)
        {
            double number = 0.00009;

            string numberFromToString = number.ToString("0." + new string('#', 339));//0.00009

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

我们也可以声明一个类FormatStrings,将339个#字符声明为一个字符串常量DoubleFixedPoint,这样用起来也会更方便:

using System;

namespace NetCoreFloat
{
    public static class FormatStrings
    {
        public const string DoubleFixedPoint = "0.###################################################################################################################################################################################################################################################################################################################################################";
    }

    class Program
    {
        static void Main(string[] args)
        {
            double number = 0.00009;

            string numberFromToString = number.ToString(FormatStrings.DoubleFixedPoint);//0.00009

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

参考文献:

Converting numbers to strings without scientific notation in C#

Double to string conversion without scientific notation

猜你喜欢

转载自www.cnblogs.com/OpenCoder/p/10938017.html