【Unity/C#】小数Round取整时,以0.5结尾的小数取整结果问题,Round(1.5)=2且Round(2.5f)=2

719 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

小数Round取整时,以0.5结尾的小数取整结果问题,Round(1.5)=2,并且Round(2.5f)=2 ???结果很离谱,问题出在哪里?

测试 UnityEngine.Mathf.Round、UnityEngine.Mathf.RoundToInt、System.Math.Round及其重载,看一下输出结果:

 测试代码:

        Debug.Log(Mathf.Round(1.5f));               //2
        Debug.Log(Mathf.Round(2.5f));               //2
        Debug.Log(Mathf.Round(3.5f));               //4
        Debug.Log(Mathf.Round(4.5f));               //4

        Debug.Log(Mathf.RoundToInt(1.5f));          //2
        Debug.Log(Mathf.RoundToInt(2.5f));          //2
        Debug.Log(Mathf.RoundToInt(3.5f));          //4
        Debug.Log(Mathf.RoundToInt(4.5f));          //4

        Debug.Log(System.Math.Round(1.5f));         //2
        Debug.Log(System.Math.Round(2.5f));         //2
        Debug.Log(System.Math.Round(3.5f));         //4
        Debug.Log(System.Math.Round(4.5f));         //4

        Debug.Log(System.Math.Round(1.5f,System.MidpointRounding.AwayFromZero));    //2
        Debug.Log(System.Math.Round(2.5f,System.MidpointRounding.AwayFromZero));    //3
        Debug.Log(System.Math.Round(3.5f,System.MidpointRounding.AwayFromZero));    //4
        Debug.Log(System.Math.Round(4.5f,System.MidpointRounding.AwayFromZero));    //5

        Debug.Log(System.Math.Round(1.5f,System.MidpointRounding.ToEven));          //2
        Debug.Log(System.Math.Round(2.5f,System.MidpointRounding.ToEven));          //2
        Debug.Log(System.Math.Round(3.5f,System.MidpointRounding.ToEven));          //4
        Debug.Log(System.Math.Round(4.5f,System.MidpointRounding.ToEven));          //4

Unity取整函数: UnityEngine.Mathf.Round/UnityEngine.Mathf.RoundToInt 机制相同(向偶取整),如果数字结尾是 .5,从而使它处于两个整数正中间(其中一个是偶数,另一个是奇数),则返回偶数。

C#的Math取整函数,默认参数与Mathf相同,但可以通过MidpointRounding枚举参数指定规则:

MidpointRounding枚举值:(Unity中只有AwayFromZero和ToEven两个参数可用) 

  • AwayFromZero:舍入到最接近的数字的策略,当一个数字在两个其他数字的中间,将舍入到离零最近的数字。
  • ToEven:舍入到最接近的数字,当某个数字在两个其他数字的中间,将舍入到最接近的偶数。(向偶取整)

如果对.5小数有较高要求,可以使用,保证结果正确性System.Math.Round(1.5f,System.MidpointRounding.AwayFromZero);