Java Double increment

时间秒杀一切 提交于 2019-12-25 06:57:14

问题


I have a double var

public double votes(){
    double votexp = 0;

      for(Elettore e:docenti.values()){
        if(e.getVoto()==true)          //everytime this is true increment by 1
        {
            votexp+=1.0;
        }   
    }
    for(Elettore e:studenti.values()){
        if(e.getVoto()==true)         //everytime this is true increment by 0.2
        {
            votexp+=0.2;
        }
    }
    for(Elettore e:pta.values()){
        if(e.getVoto()==true)        //everytime this is true increment by 0.2
        {
            votexp+=0.2;
        }
    }
    return votexp;
}

In my case the variable shoud be incremented to 2.6 but votexp returns 2.6000000000000005 how can i fix this by using the same double var and return a double precision number ?


回答1:


You are accumulating a rounding error. The simplest thing to do is to use an long (or int and only use a double at the end. (Or a BigDecimal and double at the end, but this is overly complicated)

public double votes() {
    long votexp = 0;
    for (Elettore e : docenti.values())
        if (e.getVoto())          //everytime this is true increment by 1
            votexp += 10;
    for (Elettore e : studenti.values())
        if (e.getVoto())         //everytime this is true increment by 0.2
            votexp += 2;
    for (Elettore e : pta.values())
        if (e.getVoto())        //everytime this is true increment by 0.2
            votexp += 2;
    return votexp / 10.0;
}

double a = 26 / 10.0;
System.out.println(a);

prints

2.6

As the Double.toString() "knows" values can be imprecise, it will do a small amount of rounding. This rounding is limited so the result of operating on two double can have an error too large to hide. If you round your last result correctly, the error will be small enough it won't cause a problem.




回答2:


Try using java.math.BigDecimal class.




回答3:


Some numbers cannot be represented by double-precision floating point format exactly. Looks like an intermediate number in your calculation has this flaw, which is included in the final result.




回答4:


You could try this

(double)Math.round(value * 10) / 10

but you will never get the good result by doing addition of doubles like this




回答5:


You have to round the result, floating point numbers in Java (and basically every other environment) are not perfect, and sometimes small inaccuracies creep in.

If you're dealing with decimal numbers, there's BigDecimal, which can precisely represent what you've shown (it just can't precisely represent other things, like 1 / 3).

Alternately, you can multiply by 10, use Math.round, and divide by 10 if the problem isn't with the actual end value, but with inaccuracies that have crept in during the time you've built up that value. That happens to be case with 2.6 built up like this:

double n = 0;

n += 1;
n += 0.2;
n += 1;
n += 0.2;
n += 0.2;

System.out.println("n = " + n);     // "2.6000000000000005"
n = (double)Math.round(n * 10) / 10;
System.out.println("n = " + n);     // "2.6"

...but I don't think there's a guarantee that it will necessarily be the case with all values. (I'm not a floating point guru.)

Or just worry about it when you do the output, by truncating the output result to the appropriate level of precision.



来源:https://stackoverflow.com/questions/9413908/java-double-increment

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!