JAVA - 判斷兩個浮點數相等


JAVA - 判斷兩個浮點數相等

背景知識

float型和double型是JAVA的基本類型,用於浮點數表示,在JAVA中float型占4個字節32位,double型占8個字節64位,一般比較適合用於工程測量計算中,其在內存里的存儲結構如下:

float型: 
符號位(1 bit) 
指數(8 bit) 
尾數(23 bit) 
double型: 
符號位(1 bit) 
指數(11 bit) 
尾數(52 bit) 
注意:從左到右是從低位到高位,而在計算機內部是采用逆序存儲的。 

JAVA中float型和double型是不能被計算機精確存儲的。以double類型數據1.10舉例計算機如何將浮點型數據轉換成二進制存儲: 
整數部分:1,轉換成二進制1

小數部分:0.1 
0.1*2=0.2取整數部分0,基數=0.2 
0.2*2=0.4取整數部分0,基數=0.4 
0.4*2=0.8取整數部分0,基數=0.8 
0.8*2=1.6取整數部分1,基數=1.6-1=0.6 
0.6*2=1.2取整數部分1,基數=1.2-1=0.2 
0.2*2=0.4取整數部分0,基數=0.4 
···

直至基數為0。

1.1用二進制表示為:1.000110……,即0.1 = 0*2^(-1)+0*2^(-2)+0*2^(-3)+1*2^(-4)+……而double型的小數部分只有52位,當向后計算 52位后基數還不為0時,后面的部分只能舍棄,從這里可以看出float型、double型並不能准確表示每一位小數。

因此。程序中應盡量避免浮點數的比較。在循環中,檢測兩個浮點數是否相等需要格外小心,如下的for循環可能永遠不會結束:

for(double i = 0; i != 10; i += 0.1);

浮點數能表示的精度是有限的,在計算過程中不可避免的會出現截尾而損失精度,所以如果要判斷一個浮點數double_x是否等於0,用double_x == 0這樣的判斷是不合適的,如果double_x是一系列計算的結果或者是外部傳感器的輸入值,那么它幾乎不可能是0,它大概率是一個接近0的小數,比如0.000002,

比較double數據是否相等的方法

方法一:若精度要求不高,比如因為傳感器有誤差,小於0.001的數都可以認為等於0,那么就定義epsilon = 0.001:

  1.  
    final double epsilon = 0.001;
  2.  
    double double_x = 0.0;
  3.  
    if(Math.abs(double_x - 0) < epsilon)
  4.  
    {
  5.  
        System.out.println( "true");
  6.  
    }

方法二:轉換成字符串之后用equals方法比較 

如果要比較的兩個double數據的字符串精度相等,可以將數據轉換成String然后借助String的equals方法來間接實現比較兩個double數據是否相等。

Double.toString(double_x).equals(Double.toString(double_y))

注意:這種方法只適用於比較精度相同的數據,並且是只用用於比較是否相等的情況下,不能用來判斷大小。
方法三:轉換成Long之后用==方法比較

使用Sun提供的Double.doubleToLongBits()方法,該方法可以將double轉換成long型數據,從而可以使double按照long的方法(<, >, ==)判斷是否大小和是否相等。

  1.  
    Double.doubleToLongBits( 0.01) == Double.doubleToLongBits(0.01)
  2.  
    Double.doubleToLongBits( 0.02) > Double.doubleToLongBits(0.01)
  3.  
    Double.doubleToLongBits( 0.02) < Double.doubleToLongBits(0.01)

方法四:使用BigDecimal類型的equals方法或compareTo方法

類加載:

import java.math.BigDecimal;

使用字符串形式的float型和double型構造BigDecimal:BigDecimal(String val)。BigDecimal的euquals方法是先判斷要比較的數據類型,如果對象類型一致前提下同時判斷精確度(scale)和值是否一致;compareTo方法則不會比較精確度,把精確度低的那個對象轉換為高精確度,只比較數值的大小。

  1.  
    System.out.println( new BigDecimal("1.2").equals(new BigDecimal("1.20"))); //輸出false
  2.  
    System.out.println( new BigDecimal("1.2").compareTo(new BigDecimal("1.20")) == 0); //輸出true
  3.  
     
  4.  
    System.out.println( new BigDecimal(1.2).equals(new BigDecimal("1.20"))); //輸出false
  5.  
    System.out.println( new BigDecimal(1.2).compareTo(new BigDecimal("1.20")) == 0); //輸出false
  6.  
     
  7.  
    System.out.println( new BigDecimal(1.2).equals(new BigDecimal(1.20))); //輸出true
  8.  System.out.println( new BigDecimal(1.2).compareTo(new BigDecimal(1.20)) == 0);//輸出true

原地址:https://blog.csdn.net/bupa900318/article/details/80553695


免責聲明!

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



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