.NET Core中Double与Int32相乘的精度显示差异问题咨询
.NET Core中Double与Int32相乘的精度显示差异问题咨询
大家好,最近我在折腾不同.NET版本下数值运算的精度表现时,碰到了一个挺有意思的问题,想跟大家探讨下。我写了一段测试代码,用来对比Decimal、Double、Single这几种浮点类型和Int32相乘后的输出差异,结果发现Double的表现有点特殊:
using System; using System.Linq; public class Program { public static void Main() { Decimal decimalVal = 9.38M; Double doubleVal = 9.38; Single singleVal = 9.38F; Int32 i = 100; Console.WriteLine(decimalVal*i); // 输出 "938.00" Console.WriteLine(doubleVal*i); // .NET Core+版本输出 "938.0000000000001",.NET Framework 4.7.2输出 "938" Console.WriteLine(singleVal*i); // 输出 "938" var doubleResult = doubleVal*i; var doubleBytes = BitConverter.GetBytes(doubleResult); var str = string.Join(" ", doubleBytes.Select(x => Convert.ToString(x, 2).PadLeft(8, '0'))); Console.WriteLine(str); // 不管是.NET Core+还是.NET Framework 4.7.2,输出的字节序列都是一样的: // 00000001 00000000 00000000 00000000 00000000 01010000 10001101 01000000 } }
从代码运行结果能看到几个关键点:
- Decimal类型运算后输出是"938.00",完全符合它的高精度特性;
- Single类型不管在哪个.NET版本下都输出"938";
- 最核心的疑问点在Double和Int32相乘的结果上:.NET Core+会把末尾的微小精度差异"938.0000000000001"显示出来,但.NET Framework 4.7.2却直接显示成了"938"。不过有意思的是,我把运算后的Double值转成字节序列后,两个版本的结果完全一致——这说明实际存储的数值是同一个,只是Console.WriteLine的默认格式化规则在不同.NET版本里被调整过。
我现在特别好奇,为什么微软会在.NET Core里改变这种显示逻辑?是为了更精准地呈现浮点数值的真实存储状态,还是有其他底层的设计考量?有没有大佬能帮忙拆解下这个现象背后的原因呀?
备注:内容来源于stack exchange,提问作者David Klempfner
相关产品推荐
相关产品推荐

