Java双重平等 [英] Java double equality

查看:143
本文介绍了Java双重平等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在比较双打时遇到问题。比较负责停止一个周期。代码运行正常,但是突然之间,循环永远不会停止。将来自centroidList的dimVal的值与被计算的温度变量(粗体位)进行比较。代码总是输入if,如果我使用!=或==,这并不重要。打印出来的值完全一样。什么是错误?

I'm having a problem in comparing doubles. The comparison is responsible for stopping a while cycle. The code runs fine, but then suddenly, the cycle never stops. The values from centroidList's dimVal are being compared to the temp variable which is calculated(the bold bit). The code always enters the if, it doesn't matter if I use "!=" or "==". Printed out the values, they are exactly the same. What is wrong?

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

}

推荐答案

由于在计算机内存中表示十进制数(float,double),您不应该直接比较它们 - 应该使用deltas:

Due to representation of decimal numbers in computer memory (float, double) you shouldn't compare them directly - you should use deltas:

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

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

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

But I strongly recommend you using some other types which are applicable. Maybe in your case integer/long is suitable? If no, and you need exact precision please use BigDecimal class instances. Also please remember to construct them from strings.

关于控制台输出,java会欺骗你(; - 它使用某种近似(在内存中0.1是几乎'0.1,它接近0.(9))。

Regarding the console output, java is tricking on you (; - it's using some kind of approximation (in memory 0.1 is 'almost' 0.1, it's rather closer to 0.(9)).

这篇关于Java双重平等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆