C#中Double类型乘100或Math.Pow计算结果不准确的原因咨询
为什么C#中double类型乘以100会出现精度偏差?
这其实是**IEEE 754双精度浮点数(也就是C#里的double类型)**的固有特性导致的,咱们掰开揉碎了说:
核心原因:十进制小数无法精确转换为二进制
double是用二进制来存储数值的,它的底层是二进制科学计数法——就像我们用十进制写1.23×10^5一样,double用二进制的尾数和指数来表示数值。但问题是,很多十进制小数在二进制里是无限循环的小数,就像十进制里1/3永远是0.333...没法精确表示一样。
比如你用到的70883187.82,这个十进制数转换成二进制时,无法被精确存储,double实际保存的是一个非常接近它的近似值。当你乘以100(或者Math.Pow(10,2))时,这个微小的近似误差就被放大了,最终得到的结果就会和预期的整数有细微偏差,也就是你看到的7088318781.999999。
你可以用这段代码验证一下70883187.82的真实存储值:
double original = 70883187.82; // 用G17格式输出,能看到double实际存储的完整精度值 Console.WriteLine(original.ToString("G17"));
运行后会发现,它的真实值其实是70883187.819999996左右,乘以100之后自然就变成了7088318781.999999。
怎么解决这个问题?
如果你的场景需要精确的十进制计算(比如财务、货币、金额这类对精度敏感的场景),别用double,改用C#里的decimal类型。decimal是专门为十进制小数设计的,用128位存储,能精确表示十进制小数,不会出现这种二进制转换的误差。
比如换成decimal之后,计算就完全精确了:
decimal original = 70883187.82m; // 注意后缀m,表示decimal字面量 decimal result = original * 100; Console.WriteLine(result); // 输出:7088318782
内容的提问来源于stack exchange,提问作者Jonathan Wadin
相关产品推荐
相关产品推荐

