舍入与浮点数相等性的关系:Math.Round后直接判等是否正确?
用Math.Round后直接判断double相等的做法是否正确?
结论:这种做法不可靠,大概率会在某些场景下失效,原因如下:
- double是二进制浮点数,本质上无法精确表示很多十进制小数,哪怕是两位小数。比如0.01这个值,在二进制里是无限循环的近似值,
Math.Round(x,2)得到的结果只是一个接近目标十进制值的二进制近似,而非精确值。 - 举个实际的例子:假设
x = 0.005,y = 0.014,按照十进制四舍五入规则,两者保留两位小数都是0.01,但由于二进制存储的精度问题,Math.Round(x,2)和Math.Round(y,2)得到的double值可能存在极其微小的差异,直接用==判断会认为两者不相等。 - 另外,
Math.Round默认采用的是「银行家舍入法」(四舍六入五成双),如果你的业务场景需要的是常规的四舍五入逻辑,Round的结果本身就不符合预期,后续的相等判断自然没有意义。
如果要正确判断两个double数值是否在业务上“相等”,更稳妥的方式是:
- 计算两数的绝对差值,和业务允许的误差阈值(比如
1e-6,根据实际需求调整)比较:
if (Math.Abs(x - y) < 1e-6) { // do something }
- 如果业务严格要求基于两位十进制小数的相等判断,建议改用
decimal类型——它是十进制浮点数,能精确表示两位小数,经过Math.Round后可以安全地用==做精确判断。
内容的提问来源于stack exchange,提问作者Dragno
相关产品推荐
相关产品推荐

