Another developer has given me an algorithm that returns a series of strings that contain stringified doubles. I am building unit tests against these string outputs. About 80% of the time I run my unit tests they all pass. The other 20% of the time slight variations occur in the double portion of the returned strings. For example:
Expected: ((B,D),(C,A)); : 0.05766153477579324
Found: ((B,D),(C,A)); : 0.05766153477579325
Expected: (B,(C,(A,D))); : 0.0017518688483315935
Found (B,(C,(A,D))); : 0.001751868848331593
I know that double computations can be imprecise, but I have never heard of them being variant. I am assured by the algorithm author that the algo is deterministic. The way that the double is being toStringed is:
for(Tree gt: geneTrees){
double prob = probList.next();
total += prob;
result.append("\n" + gt.toString() + " : " + prob);
}
I am at a bit of a loss explain how this variation is possible. Any ideas?
Just based on the summing that you’re doing, I suspect that this might be caused by the issue that double addition is not quite commutative or associative — you’ll get different rounding errors if you add doubles in a slightly different order.
Just add a small epsilon for your unit tests, basically.