java四捨五入成整數的方法

    在java的Math類中,提供了許許多多的和數學計算有關的方法,其中也包括取整的,關於取整的有向下取整的floor(double d)返回值double,rint(double d),round(double d)和round(float f)。


    但是,其中和四捨五入相近的方法只有rint和round方法,如果單獨使用這兩個方法的話,所得到的結果和我們預期的結果不一樣,

    比如round(-1.5)所得到的結果是-1,而不是我們預期的-2;

    而rint(-1.5)得到的結果是-2.0,但是rint(2.5)得到的結果卻是2.0,和我們預期的3.0也不一樣

    我們分析一下爲什麼會這樣子,首先看一下round方法的API:

Returns the result of rounding the argument to an integer. The result is equivalent to (long) Math.floor(d+0.5).

Special cases:

  • round(+0.0) = +0.0
  • round(-0.0) = +0.0
  • round((anything > Long.MAX_VALUE) = Long.MAX_VALUE
  • round((anything < Long.MIN_VALUE) = Long.MIN_VALUE
  • round(+infinity) = Long.MAX_VALUE
  • round(-infinity) = Long.MIN_VALUE
  • round(NaN) = +0.0
Parameters
d the value to be rounded.
Returns
  • the closest integer to the argument.

即返回一個和參數相近的整型,其結果相當於(long) Math.floor(d+0.5)的值,對於Math.floor(double d)方法,其結果是d向下取整,所以對於round(-1.5)來說,它的返回值是要加上0.5再向下取整,也就是-1.5+0.5=-1.0,1.0向下取整還是1.0,所以返回的是長整型1,但是計算正數的時候就沒有這個問題。比如說round(1.5),計算的就是(long)(1.5+0.5)=(long)2.0=2L,所以對於round方法來說對於負數四捨五入所得到的結果是不正確的。


    然後我們來看一下rint方法的API,這個方法與四捨五入差的有點遠。

public static double rint (double d)

Added in API level 1

Returns the double conversion of the result of rounding the argument to an integer. Tie breaks are rounded towards even.

Special cases:

  • rint(+0.0) = +0.0
  • rint(-0.0) = -0.0
  • rint(+infinity) = +infinity
  • rint(-infinity) = -infinity
  • rint(NaN) = NaN
Parameters
dthe value to be rounded.
Returns
  • the closest integer to the argument (as a double).


    這個方法也是返回一個和參數相近的整型,當有兩個整數的時候,會返回偶數的那個。

也就是說,當遇到幾點五的時候,纔會遇到兩個整數,所以對於rint(-1.5)來說,會有-1.0和-2.0兩個整數與-1.5相近,但是他會取偶數-2.0,。對於rint(-1.3)只有一個整數-1.0與-1.3接近,所以此時不會有誤差。但是對於rint(2.5),有2.0和3.0與2.5接近,他會返回與我們預期不一樣的偶數2.0,rint(-2.5)會返回-2.0,所以對於rint方法,當遇到偶數點五的時候,結果會不一樣。

    綜合上述,如果想用round方法就得解決負數問題,所以可以用絕對值Math.abs方法來解決。下面爲代碼:

方法一:

public double run(double num){
    double a=Math.signum(num); //判斷是正數負數還是0,負數返回-1.0,正數返回1.0
    if(a<0.0)
        return 0.0-Math.round(Math.abs(num));
    return Math.round(num);
}

    如果想用rint方法就得解決偶數點五的問題,下面爲代碼:

方法二:

public double run(double num){
   if(Math.floor(Math.abs(num))%2!=0)
       return Math.rint(num);
   if(five(num))
       if(Math.signum(num)<0.0)
       return Math.rint(num)-1.0;
   else if(Math.signum(num)>0.0)
       return Math.rint(num)+1.0;
   return Math.rint(num);

}
public boolean five(double n){
    String[] split = String.valueOf(n).split("\\.");
    if(split[1].startsWith("5"))
        return true;
    else return false;
}

    當然也有其他方法,比如用保留小數的方法string的格式化方法都行   

因爲方法二效率低,所以建議使用方法一。

本人第一次寫博客,還是學生,所以有不足之處請指正,請諒解不足或錯誤之處,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章