2013-04-03 88 views
0

我在比较双打时遇到问题。该比较负责停止一段时间周期。代码运行良好,但突然间,周期从未停止。来自centroidList的dimVal的值将与计算出的临时变量(粗体位)进行比较。代码总是输入if,如果使用“!=”或“==”,则无关紧要。打印出来的值完全一样。哪里不对?Java双等于

package clusters; 

import java.util.LinkedList; 

public class KMeansV2 { 

    LinkedList<Record> table; 
LinkedList<Centroid> centroidList; 
LinkedList<Double> intervalList; 
boolean clusterStop; 

int meassureType; 
int prec=10000000; 

KMeansV2() 
{ 
    Read read=new Read(true,"BrCa_HD_full.xlsx"); 
    table=new LinkedList<Record>(read.table); 
    centroidList=new LinkedList<Centroid>(); 
    CreateCentroids(2); 
    SetMeassureType(1); 
    while(clusterStop==false) 
    { 
     UpdateRecords(); 
     UpdateClusters(); 
    } 
    Output(); 
} 

public void SetMeassureType(int meassureType) 
{ 
    this.meassureType=meassureType; 
} 

public void CreateCentroids(int centroidCount) 
{ 
    if(centroidList.isEmpty()) 
    { 
     for(int i=0;i<centroidCount;i++) 
     { 
       centroidList.add(new Centroid(table.get(0).values.size(),i)); 
     } 
    } 
    else 
    { 
     centroidList.clear(); 
     for(int i=0;i<centroidCount;i++) 
     { 
       centroidList.add(new Centroid(table.get(0).values.size(),i)); 
     } 
    } 

} 

public void UpdateRecords() 
{ 
    for(int i=0;i<table.size();i++) 
    { 
     table.get(i).Update(centroidList, meassureType); 
    } 
} 

public void UpdateClusters() 
{ 
    clusterStop=true; 
    for(int i=0;i<centroidList.size();i++) //staiga pa centroidiem 
    { 
     for(int j=0;j<table.get(0).values.size();j++) //staiga pa kolonnam 
     { 
      double sum=0; 
      double count=0; 
      for(int k=0;k<table.size();k++) //staiga pa rindam 
      { 
       if(centroidList.get(i).type==table.get(k).type) 
       { 
        sum+=table.get(k).values.get(j); 
        count++; 
       } 
      } 
      System.out.println(clusterStop); 

      double temp=(1/count)*sum; 

      **if(centroidList.get(i).dimVal.get(j)==temp); 
      { 
       System.out.println(centroidList.get(i).dimVal.get(j)+" != "+(1/count)*sum); 
       clusterStop=false; 
      }** 

      centroidList.get(i).dimVal.set(j,temp); 
     } 
     System.out.println(clusterStop); 
    } 
} 

public void Output() 
{ 
    LinkedList<String> types=new LinkedList<String>(); 
    for(int i=0;i<table.size();i++) 
    { 
     if(!types.contains(table.get(i).realType)) 
     { 
      types.add(table.get(i).realType); 
     } 
    } 

    for(int i=0;i<centroidList.size();i++) //staiga pa centroidiem 
    {  
     for(int j=0;j<types.size();j++) //staiga pa klasem 
     { 
      int count=0; 
      for(int k=0;k<table.size();k++) // staiga pa rindam 
      { 
       if(table.get(k).type==i && table.get(k).realType.equals(types.get(j))) 
       { 
         count++;  
       } 
      } 
      System.out.println("Centroid "+(i+1)+" has "+count+" of type "+types.get(j)); 
      //kMeansUI.UpdateLog("Centroid "+(i+1)+" has "+count+" of type "+types.get(j)); 
     } 
    } 

    for(int i=0;i<centroidList.size();i++) 
    { 
     int count=0; 
     for(int j=0;j<table.size();j++) 
     { 
      if(table.get(j).type==i) 
      { 
       count++; 
      } 
     } 
     System.out.println("Cluster "+i+" has "+count+" records."); 
     //kMeansUI.UpdateLog("Cluster "+(i+1)+" has "+count+" records."); 
    } 
    //kMeansUI.UpdateLog("/-------------------------------------------------------------------------/"); 

} 

public static void main(String[] args) 
{ 
    KMeansV2 test=new KMeansV2(); 
} 

}

+3

你可能会更好的使用'BigDecimal'进行双重算术和比较。看看[每个计算机科学家应该了解的浮点运算](http://docs.sun.com/source/806-3568/ncg_goldberg.html)。 –

回答

6

由于计算机内存十进制数表示(浮动,双),你不应该直接对它们进行比较 - 你应该使用增量:

double x = 123.123; 
    double y = 123.1234; 
    double delta = 0.01; 

    boolean areEqual = Math.abs(x - y) <= delta 

但我强烈建议你使用了一些适用的其他类型。也许在你的情况下integer/long是适合的?如果不是,并且您需要准确的精确度,请使用BigDecimal类实例。也请记住从字符串构造它们。

关于控制台输出,Java是你(欺骗; - 这是使用某种近似的(在存储器0.1为“几乎” 0.1,它是相当接近0(9))

1

由于。浮点数(double是双精度浮点数)被绝大多数现代处理器所处理,在它们上执行操作很少能得到确切的值

所以你基本上可以选择。自己做一些比较方法,允许有一定的误差。

+0

精度只需要在一个点上,所以我会先使用四舍五入,如果我有时间,将使用BigDecimal,谢谢所有响应:) – MustSeeMelons

1

如果(centroidList.get(i).dimVal.get(j)< ---你确定这是返回一个双?在打印出变量以检查它们的相等性时请注意。它们的字符串表示并不总是与它们的等式表示相同。

+0

dimVal列表包含double,我确实尝试了DoubleValue( )没有效果。 – MustSeeMelons