浮点数(float、double)精度损失问题

前言

以前简单了解过浮点数的精度损失问题,但是没有系统整理过。前段时间踩到了坑,是long类型转float类型进行计算与预期结果出现了差异,明明结果应该是整数但是却差了1点属性值,这里感谢QA测试的仔细。

原因

浮点数在计算机中是用二进制表示的,而有些十进制小数无法用二进制精确表示,例如0.1,0.2,0.3等。这样在进行浮点数运算时,就会出现一些误差,导致结果不准确。
详细原因就不赘述了,可以参考下面的两篇博客。
5分钟彻底搞懂"浮点数精度丢失"问题
Unity3D研究院之被坑了的浮点数的精度

解决方案

1. 如果对精度要求不是特别高,可以使用Math类中的一些方法,例如Math.RoundMath.FloorMath.Ceiling等,可以对浮点数进行四舍五入,向下取整,向上取整等操作。

//Math.Round是我们在实际开发中经常使用的进行四舍五入的方法,但是一定要注意,
//C#中的Round()不是四舍五入,是符合IEEE标准的四舍五入,
//具体是四舍六入,如果遇5则前一位如果是偶数则舍掉,如果是奇数则进一位。
double num1 = Math.Round(2.455,2);//得到的值是2.46

//使用Math.Round()的重载函数,四舍五入,保留两位数据
//这种方式才是我们中国人理解的四舍五入。
double num2 = Math.Round(2.455,2,MidpointRounding.AwayFromZero);//得到的值是2.46

2. 使用 decimal 类型,它拥有更高的精度。虽然decimal也会出现精度丢失问题,但是一般业务需求是没问题的。
3. 如果需求数值精确,那么就尽量避免使用浮点数,比如我们项目中战斗系统涉及的数值都是用万分比去做的,10000代表1,计算就变成了整数间的计算。
4. 使用高精度运算的类库,比如BigDecimal,但是要注意传入字符串而不是浮点数,否则还是会有误差。

你可能感兴趣的:(unity,c#,开发语言)