应用笔记 · 2023年9月28日

C# 用于表示小数的数据类型 float、double、decimal对比

首先这3个数据类型都可以表示带小数的数据,而且都是浮点数,区别在于表示数据的精度和范围是不同的,具体如下:

C# 支持的预定义浮点类型
注意:float 不用说了,double 和 decimal 分别强调于表示数的范围大小更大 和 表示数的精度更高。

 

○ 在使用浮点型的常量时,默认情况下,出现在赋值运算符右侧的实数就是double类型,如果希望数据被指定对应的数据类型,可以使用相应的后缀:

(1)单精度浮点型使用后缀 f 或 F,示例:

float f = 17.5F;

(2)decimal 类型使用后缀 m 或 M,示例:

decimal m = 17.5m;

(3)双精度浮点型使用后缀 d 或 D,示例:

double d = 3D;

 

○ 实际问题中浮点数的数据类型选择问题,我们自己写的程序应该怎样选择合适的数据类型呢?
(1)当需求更强调小数点右侧的位数时,优先选择decimal 类型,特别是财务、货币、利率等。示例:

double a = 0.3 – 0.2;

double b = 0.2 – 0.1;

Console.WriteLine(a == b);

Console.WriteLine(a == 0.1);

Console.WriteLine(b == 0.1);

decimal x = 0.3m – 0.2m;

decimal y = 0.2m – 0.1m;

Console.WriteLine(x == y);

Console.WriteLine(x == 0.1m);

Console.WriteLine(y == 0.1m);

的结果是

0.1 可以由 decimal 实例精确表示,而没有精确表示 0.1 的 double 或 float 实例
以上示例可见,0.1 可以由 decimal 精确表示,而没有精确表示 0.1 的 double 或 float ,因此当使用 double 或 float 时,算术计算可能会出现意外的因浮点数据表示造成的舍入错误,而这种错误不会有任何的提示!这可能是非常严重的程序隐患。

(2)对性能有更高需求,且在保证算术运算是可靠的前提下使用 float或double 代替 decimal,另外就是对降低存储需求有要求时。这时对类似于(a==b)的表达式可以修改为Math.Abs(a-b)<1e-5,以避免因浮点数据表示造成的舍入错误。

 

○ 不同类型之间的混合运算
(1)在表达式中可以 将 整型类型与 float 和 double 类型混合使用,此时整型类型隐式转换为其中一种浮点类型,且必要时,float 类型隐式转换为 double。

(2)也可以在表达式中混合使用 整型类型 和 decimal 类型,此时整型类型隐式转换为 decimal 类型

(3)但是不能在表达式中将 decimal 类型与 float 和 double 类型 直接混合使用。在这种情况下,如果要执行算术运算、关系运算,必须将操作数显式(强制)转换为 decimal 或反向转换,示例:

double a = 1.0;

decimal b = 2.1m;

Console.WriteLine(a + (double)b);

Console.WriteLine((decimal)a + b);

作者:roy20066 https://www.bilibili.com/read/cv18393935/ 出处:bilibili