判斷浮點數是否相等


1. 浮點數 == 什么時候出現問題

1.1 都為小數或整數,不參與運算

/**
*無論 a = 0.1 or 1.0 or 1.1   結果都為true
*/
public static void main(String[] args){
	double a = 0.1;
	double b = 0.1;
	float c = 0.1f;
	float d = 0.1f;

    System.out.println("a==b : "+ (a == b));

	System.out.println("c==d : "+ (c == d));
}

1.2 參與加減法

1.2.1 純小數 + 純小數 or 純整數

public static void main(String[] args){
	double a = 0.1;
	double b = 0.1;
	float c = 0.1f;
	float d = 0.1f;
    
	a  = a + 1 - 1; //不論是 1 or 1.0 or 1.1,只要大於0.101 均輸出 false
   	//b = b + 1 - 1; 若執行此行,則輸出 true
	System.out.println("a==b : "+ (a == b)); //輸出 false
    
	c = c + 0.1f - 0.1f;
    
	System.out.println("c==d : "+ (c == d)); //輸出 true
}

1.2.2 純整數 + 純小數 or 純整數

public static void main(String[] args){
    double a = 1;
    double b = 1;
    float c = 1f;
    float d = 1f;

    a  = a + 0.1 - 0.1;

    c = c + 1f - 1f;

    System.out.println("a==b : "+ (a == b)); // true

    System.out.println("c==d : "+ (c == d)); // true
}

1.2.3 非純整數 + 純小數 or 純整數

public static void main(String[] args){
    double a = 1.1;
    double b = 1.1;
    float c = 1.1f;
    float d = 1.1f;

    a = a + 1 - 1;

    c = c + 0.1f - 0.1f;

    System.out.println("a==b : "+ (a == b));// true

    System.out.println("c==d : "+ (c == d));// true
}

1.3 個人總結

以上測試都是放屁,換個數值又會出問題,規律我是不會去找了,還是用別的方法吧

2. == 和 equals 的區別

== equals
基礎數據類型:比較他們的值是否相等
引用數據類型:比較的是引用的地址是否相同 所指向對象的內容是否相等

String 類的 equals()方法源碼

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

簡單說,判斷規則

  1. 引用不同,不相等
  2. 類型不同,不相等
  3. 長度不同,不相等
  4. 字符不同,不相等

當且僅當參數不是null且是String對象表示與此對象相同的字符序列時,結果為true

3.浮點數相等的判斷方法

3.1 絕對值比較,看精度要求情況

private static void doubleCompare(double dby,double dbx){
    final double epsilon = 0.0000001;
    if(Math.abs(dby - dbx) < epsilon){
        System.out.println("絕對值比較結果: true");
    }else{
        System.out.println("絕對值比較結果: false");
    }
}

3.2 轉換成字符串后使用 equals 方法比較

private static void doubleCompare(double dby,double dbx){
	System.out.println("字符串 equals方法比較結果 : "+ Double.toString(dby).equals(Double.toString(dbx)));
}

3.3 Double.doubleToLongBits()方法比較

public static long doubleToLongBits(double value)

根據IEEE 754浮點“雙格式”位布局返回指定浮點值的表示形式。

位63(由掩碼0x8000000000000000L選擇的位)表示浮點數的符號。 比特62-52(由掩碼0x7ff0000000000000L選擇的比特)表示指數。 比特51-0(由掩碼0x000fffffffffffffL選擇的比特)表示0x000fffffffffffffL的有效數(有時稱為尾數)。

如果參數為正無窮大,則結果為0x7ff0000000000000L

如果參數為負無窮大,則結果為0xfff0000000000000L

如果參數為NaN,則結果為0x7ff8000000000000L

在所有情況下,結果都是一個long整數,當給定longBitsToDouble(long)方法時,將生成與doubleToLongBits的參數相同的浮點值(除了所有NaN值都折疊為單個“規范”NaN值)。

  • 參數

value - 精度為 double浮點數。

  • 結果

表示浮點數的位。

private static void doubleCompare(double dby,double dbx){
	System.out.println("Long 的 == 方法比較結果 : "+ (Double.doubleToLongBits(dby) == Double.doubleToLongBits(dbx)));
}

3.4 使用BigDecimal類型的equals方法或compareTo方法

/**
* 兩種方法均先判斷構造方法參數是否相同,不同均返回 false
* compareTo 只比較數值大小,不比較比例
* equals 需要比較數值和比例大小,都相等,才返回 true,以下測試結果和預期不同,原因未知
*/
private static void doubleCompare(){
	System.out.println(new BigDecimal("0.1").equals(new BigDecimal("0.10")));  //輸出false  
	System.out.println(new BigDecimal("0.1").compareTo(new BigDecimal("0.10")) == 0); //輸出true  
    		          
	System.out.println(new BigDecimal(0.1).equals(new BigDecimal("0.10"))); //輸出false
	System.out.println(new BigDecimal(0.1).compareTo(new BigDecimal("0.10")) == 0); //輸出false  
    		     
	System.out.println(new BigDecimal(0.1).equals(new BigDecimal(0.10))); //輸出true  
	System.out.println(new BigDecimal(0.1).compareTo(new BigDecimal(0.10)) == 0);//輸出true 
}

      • public int compareTo(BigDecimal val)
        

        將此BigDecimal與指定的BigDecimal 。 通過此方法,兩個值相等但具有不同比例(如2.0和2.00)的BigDecimal對象被視為相等。 對於六個布爾比較運算符(<,==,>,> =,!=,<=)中的每一個,優先考慮該方法。 建議執行這些比較的習慣用法是: (x.compareTo(y) < op > 0) ,其中< op >是六個比較運算符之一。

        • Specified by:

          compareTo ,界面 Comparable

        • 參數

          val - BigDecimal這個 BigDecimal要比較。

        • 結果

          -1,0或1,因為該 BigDecimal在數值上小於,等於或大於 val


      • public boolean equals(Object x)
        

        將此BigDecimal與指定的Object進行相等性比較。 與compareTo不同,此方法僅考慮兩個BigDecimal對象的值和比例相等(因此通過此方法比較時2.0不等於2.00)。

        • 重寫:

          equals ,類 Object

        • 參數

          x - ObjectBigDecimal比較。

        • 結果

          true當且僅當指定的 ObjectBigDecimal其值和比例等於此 BigDecimal

        • 另請參見:

          compareTo(java.math.BigDecimal)hashCode()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM