从技术上说,decimal表示一个浮点数值类型,它对应.NET基元类型中的System.Decimal,但是,C#语言规范中并没有将其定义为浮点类型。由于它在内存中占16个字节,所以它是一个128位的数据类型,可以存储介于-79228162514264337593543950335到-79228162514264337593543950335之间的有符号浮点数值,在数字后面带有m或M后缀用来表示decimal类型。例如:
decimal v1 = 56.789m;
decimal v2 = 99.99M;
decimal的小数点后最多可以表示28个数字,所以它的精度非常高,通常使用于金融交易、精密量测和科学计算等方面。
相比较于float和double浮点数据类型,decimal要具备一些优势,比如decimal的精度和舍入是固定的,它使用十进制表示,不会因二进制浮点数的近似性而出现误点;它能够处理比其他数据类型更长的数字,最大可达28位数字,而double类型只能支持15到16位;在decimal的比较中,只要两个数值具有相同的位数和值,它们就相等,而double和float是不一定的。
decimal能够和其他数据类型进行简单的转换,同时也能够在不同平台之间进行交流,不会因为平台的不同而出现数据类型差异的问题。因为decimal不是C#基本数据类型,所以它的性能和效率是比较低的。
观察下面的例子
internal class Program
{
static void Main(string[] args)
{
decimal max = decimal.MaxValue;
decimal min = decimal.MinValue;
decimal v = 1.23m;
Console.WriteLine($"max = {max}");//最大输出值
Console.WriteLine($"min = {min}");//最小输出值
Console.WriteLine($"v = {v}");//输出值
Console.WriteLine($"v的类型为{v.GetType()}");//变量类型
Console.WriteLine($"decimal占内存大小为{sizeof(decimal)}");//内存大小
decimal result = 9.9m / 3.1m;
Console.WriteLine($"9.9 / 3.1 = {result}");//输出值
double v1 = 3.1d;
decimal v2 = 3.1m;
Console.WriteLine($"double == decimal: {v1 == (double)v2}");
Console.WriteLine($"double == double: {v1 == 3.1d}");
Console.WriteLine($"decimal == decimal: {v2 == 3.1m}");
double dd = 10000000000000000000000d;
dd += 1;
Console.WriteLine("{0:G50}", dd);
decimal ff = 10000000000000000000000m;
ff += 1m;
Console.WriteLine("{0:G50}", ff);
Console.ReadKey();
}
}
输出结果
max = 79228162514264337593543950335
min = -79228162514264337593543950335
v = 1.23
v的类型为System.Decimal
decimal占内存大小为16
9.9 / 3.1 = 3.1935483870967741935483870968
double == decimal: True
double == double: True
decimal == decimal: True
10000000000000000000000
10000000000000000000001
结果分析
当我们给10000000000000000000000m+1时,结果为10000000000000000000001,由此可见,没有发生精度损失,彻底解决浮点类型的精度损失问题。
——重庆教主 2024年1月19日