Monday 28 February 2011

Proof, if any were needed or wanted, that floating point arithmetic is not exact

Well, well, I replaced CSMTransactionVector throughout the codebase with System.Collections.Generic.List and ran the entire suite of system and unit tests. One of the test (just one, out of ~360) failed! And do you know why? It failed because the test was comparing expected floating point results with actual floating point results and we all know that floating point numbers should not be compared.

Anyway, the system test was comparing the following derived values (be amazed at the expected precision!)

Assert.AreEqual(-7347, pos.Quantity);
Assert.AreEqual(64.966093643663939, pos.AveragePrice);
Assert.AreEqual(-477305.88999999897, pos.GrossAmount);
Assert.AreEqual(-477297.82353045908, pos.NetAmount);

and all but the last were succeeding. The last test, the net amount test, was different by 15E-10!! Dunno about you but I'd normally say that they were the same LoL.

Interestingly, though, the upshot of this is that the CSMTransactionVector appears to store its contents in reverse, in the manner of a functional list, I suppose. Reversing my List after loading the data and running all the tests again meets with SUCCESS!!! Well, well, as I said at the beginning of this post!

This makes me ponder on the internals of the CSMTransactionVector. We have already determined that accessing the vector using an enumerator leads to unexpected results, but this means that using the random-access [] operator does some magic too. I wonder what happens when elements are added to the CSMTransactionVector in mid-flow?

No comments:

Post a Comment