C#中float、double与decimal的精度差异问题
C#浮点类型输出精度问题解答
先看示例代码:
// Float Console.WriteLine(123.0f); // 123 // Double Console.WriteLine(123.0); // 123 // Decimal Console.WriteLine(123.0m); // 123.0
1. 为什么decimal会保留一位小数,而float和double不会?
核心是设计定位和存储机制的差异:
decimal是专为精确十进制计算(比如金融场景)设计的,它内部存储的是十进制数字的符号、有效数字和缩放因子——123.0m的缩放因子明确标记了要保留1位小数,所以默认输出时会体现这个精度。float和double是二进制浮点类型,123.0f/123.0在二进制里就是精确的整数,没有额外的小数部分信息。Console.WriteLine默认会输出最短的等价字符串,既然123.0和123数值完全等价,自然会省略末尾的零。- 另外,
decimal的默认ToString()方法会保留它内部记录的精度,而float/double的默认ToString()只输出能准确表示数值的最短形式。
2. 能不能让float和double也保留这种精度(即使小数部分为零)?
可以,通过格式化输出字符串就能实现,本质是强制指定显示格式,而非改变类型本身的存储:
- 固定小数位数的格式化:
float fNum = 123.0f; Console.WriteLine(fNum.ToString("F1")); // 输出 123.0 Console.WriteLine(string.Format("{0:F1}", fNum)); // 同样输出 123.0 double dNum = 123.0; Console.WriteLine(dNum.ToString("F1")); // 输出 123.0 - 用通用格式符指定精度:
Console.WriteLine(123.0f.ToString("G3")); // 输出 123.0 - 自定义格式字符串:
Console.WriteLine(123.0f.ToString("#.0")); // 输出 123.0
注意:这种方式只是改变了显示的字符串样式,float和double本身的二进制存储并没有保留小数精度信息,只是在输出时强制加上了末尾的零。
内容的提问来源于stack exchange,提问作者Matthew Layton
相关产品推荐
相关产品推荐

