我在比较 double 时遇到问题。比较负责停止 while 循环。代码运行良好,但突然间,循环永远不会停止。 centroidList 的 dimVal 的值与计算出的临时变量(粗体位)进行比较。代码总是输入if,我用“!=”还是“==”都没关系。打印出来的值是完全一样的。怎么了?
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();
}
}
最佳答案
由于计算机内存中十进制数字的表示形式(浮点型、 double 型),您不应该直接比较它们 - 您应该使用增量:
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))。
关于Java 双重相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15782529/