Math.Round()函数取整结果不符合预期的问题求助
Math.Round()函数取整结果不符合预期的问题求助
嘿,这个问题其实是浮点数精度的经典坑!你遇到的情况不是Math.Round()出bug了,而是因为像36.675这样的十进制小数,在计算机用二进制浮点数(比如C#里的double类型)存储时,没办法精确表示——实际存储的值会略小于36.675,而17.675、6.675这些数的二进制存储值会略大于它们的十进制字面量。
当Math.Round()对这些近似值进行四舍五入到两位小数时:
- 略大于
x.675的数,会被判定为更接近x.68,所以进一位 - 略小于
x.675的数,会被判定为更接近x.67,所以舍去第三位
那怎么解决呢?最靠谱的办法是用**decimal类型**来处理,因为decimal是基于十进制的浮点类型,能精确表示像36.675这样的十进制小数,不会有二进制转换的精度损失。
给你两个具体的解决方式:
- 直接使用
decimal字面量(在数字后面加m)进行计算:
Math.Round(36.675m, 2); // 结果会是36.68,符合预期 Math.Round(38.675m, 2); // 同样得到38.68
- 如果你的原始数据是
double类型,先转成decimal再处理(注意:如果double本身已经是不精确的近似值,转decimal可能还是有问题,最好从源头就用decimal):
double num = 36.675; Math.Round((decimal)num, 2);
另外,如果你一定要用double类型,也可以通过指定MidpointRounding参数调整取整规则,但这只是权宜之计,本质上解决不了浮点数精度的根源问题:
Math.Round(36.675, 2, MidpointRounding.AwayFromZero);
不过这个方法在某些情况下依然会因为浮点数的近似问题出现不符合预期的结果,所以还是优先推荐用decimal类型。
备注:内容来源于stack exchange,提问作者Alsmon Albert
相关产品推荐
相关产品推荐

