Question

Assert.Equal(1000000.0, table.Convert("g", "mcg", 1.0)); // Pass
Assert.Equal(2000000.0, table.Convert("g", "mcg", 2.0)); // Pass
Assert.Equal(3200000.0, table.Convert("g", "mcg", 3.2)); // Fail
// The failing one is equal to doing the following calculation, which fails also:
Assert.Equal(3200000.0, 3.2 * 1.0 / (1.0 / 1000000.0));  // Fail
Assert.Equal(3200000.0, 3.2 * (1.0 / (1.0 / 1000000.0)));// Pass, WTF?!?!
===================================================================    
Assert.Equal() Failure
    Expected: 3200000
    Actual:   3200000
Was it helpful?

Solution

With the different order of operations, the floating point binary rounding errors appear to be propagating up differently. You can get "less surprising" but potentially slower results with the Decimal type.

3.2 * 1.0 / (1.0 / 1000000.0) -> 3200000.0000000005

(try (3.2 * 1.0 / (1.0 / 1000000.0) ).ToString("R");

3.2 * (1.0 / (1.0 / 1000000.0)) -> 3200000.0

If you don't already understand the differences between floating point and decimal types, please read: http://docs.sun.com/source/806-3568/ncg_goldberg.html

Or, if you prefer something in plainer English: http://floating-point-gui.de/

OTHER TIPS

Yoe can't see it from your code snippet, but I'm quite sure that it has something to do with the fact that your first lines (the passing ones) have a .0, whereas the failing one has something unequal to zero after the comma.

I'm sure there's something weird like 3.2000000001 coming in somewhere. Maybe from the database?

HTH!
Thomas

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top