Java的双重平等(Java double equality)

2019-10-29 08:05发布

我有在比较双打的问题。 比较负责停止while循环。 该代码运行正常,但突然,循环永远不会停止。 从centroidList的dimVal的值被比较,以由此计算的临时变量(粗体位)。 该代码总是进入,如果,如果我用也没关系“!=”或“==”。 打印出来的价值,它们是完全一样的。 怎么了?

    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();
}

}

Answer 1:

由于计算机内存十进制数(浮动,双),请直接与对方无法比拟的代表 - 你应该使用增量:

  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))。



Answer 2:

由于浮点数( double为双精度浮点数)被绝大多数现代处理器的处理,执行对他们的操作很少得到你一个确切的价值。

所以,你必须基本上选择。 比较之前无论是圆你的价值观或进行一些比较方法自己这允许一些误差。



Answer 3:

如果(centroidList.get(I).dimVal.get(J)<---你确定是返回一个双?为了检查他们平等的打印输出变量的时候要注意,他们的字符串表示并不总是相同作为他们的平等代表性。



文章来源: Java double equality