为何C#中int与decimal做除法会省略结果的.0,加减乘运算则不会?
C# decimal运算输出差异原因解释
你观察到的现象本质是decimal类型的存储规则、算术运算精度推导规则、默认字符串格式化逻辑三者共同作用的结果,a/b的运算结果始终是decimal类型,不存在转为int的情况,只是显示形式不同。
1. decimal和float/double的核心存储差异
decimal是十进制浮点类型,内部存储结构包含三个核心字段:符号位、整数系数、缩放系数(即10的负N次方,N代表保留的小数位数)。也就是说decimal会显式存储当前值的小数位数,比如5.0m的小数位是1,5m的小数位是0,二者数值相等但存储的小数位参数不同。
而float/double是二进制浮点类型,仅存储二进制科学计数法的指数和尾数,不记录十进制小数位数,转字符串时会直接输出能唯一标识该值的最短十进制字符串,所以不会出现多余的末尾.0。
2. decimal不同算术运算的精度推导规则
C#对decimal的算术运算有明确的精度继承规范:
- 乘法运算:结果的小数位数固定为两个操作数的小数位数之和。
你的示例中a是int类型,隐式转为decimal时小数位为0,b=5.0m的小数位是1,所以a*b的结果小数位为0+1=1,就算数值恰好是整数225,也会存储为225.0m,输出时自然带.0。 - 除法运算:结果的小数位数会自动归一化,在保证数值精度完全准确的前提下,尽可能去掉无意义的末尾零,调整为最少的小数位数。
你的示例中45 / 5.0m的结果恰好等于整数9,不需要小数位即可精确表示,所以运算后会自动将结果的小数位调整为0,存储为9m,输出就显示为9。而45 / 5.5m的结果无法用更少的小数位精确表示,所以会保留足够的小数位,输出长串小数。
3. 验证结论的代码示例
你可以通过以下代码确认运算结果始终是decimal类型,只是显示形式不同:
int a = 45; decimal b = 5.0m; var result = a / b; // 验证类型是decimal Console.WriteLine(result.GetType().FullName); // 输出System.Decimal // 强制指定输出格式即可显示小数位 Console.WriteLine(result.ToString("F2")); // 输出9.00
内容的提问来源于stack exchange,提问作者nisar007
相关产品推荐
相关产品推荐

