Uh oh!
There was an error while loading. Please reload this page.
Fix MatchNumberWithTolerance to better compare floating-point values - #1145
Conversation
tannergooding
commented
Oct 4, 2018
A good example of a place where the previous algorithm would have been less than ideal is: staticvoidMain(string[]args){intxi=16777217;intyi=16777219;intzi=yi-xi;floatxf=xi;floatyf=yi;floatzf=yf-xf;// 16777219 - 16777217 = 2Console.WriteLine($"{yi} - {xi} = {zi}");// 16777220 - 16777216 = 4Console.WriteLine($"{yf:G9} - {xf:G9} = {zf:G9}");// 0x4B800002 - 0x4B800000 = 0x40800000Console.WriteLine($"0x{BitConverter.SingleToInt32Bits(yf):X8} - 0x{BitConverter.SingleToInt32Bits(xf):X8} = 0x{BitConverter.SingleToInt32Bits(zf):X8}");}As you can see, the inputs are The new algorithm rounds each input (both expected and actual) to a given number of significant digits (currently defaulting to |
| public abstract partial class BaseTestBaseline : BaseTestClass | ||
| { | ||
| public const decimal Tolerance = 10_000_000; | ||
| public const int DigitsOfPrecision = 7; |
There was a problem hiding this comment.
public [](start = 8, length = 6)
nit: can it be internal?
There was a problem hiding this comment.
Maybe, but the existing code already had the previous constant as public.
There was a problem hiding this comment.
It looks like it is used by inherited classes. And this is "just tests" so internal vs. public may not make that much of a difference.
In reply to: 222529405 [](ancestors = 222529405)
sfilipi
commented
Oct 4, 2018
Thanks for the change, Tanner. Did you want to try enabling any tests with the PR, to see if it helps? In reply to: 426870598 [](ancestors = 426870598) |
danmoseley
commented
Oct 4, 2018
Will this allow you to remove the tolerance related disables on #1008 before you merge that? |
Uh oh!
There was an error while loading. Please reload this page.
Couple of cases where this is failing // digitsOfPrecision = 1 , variance = 0.1 |
Anipik
commented
Oct 4, 2018
similarly for f1 = 0.7099695, f2 = 0.6931915 delta should be one but its value 0.02 but its value is 0.020000000000000018 |
tannergooding
commented
Oct 5, 2018
@Anipik, you have to decide which rounding behavior is the most desirable as each has its pros/cons. I've defaulted to the IEEE default rounding mode as that tends to have the best overall behavior for the binary floating-point format. The algorithm should be generally sufficient for
|
This updates
MatchNumberWithToleranceto better compare floating-point values and enables it on Windows.The previous algorithm was not properly accounting for the distribution of binary floating-point values and would not allow a match for numbers that could have been reasonably considered as equivalent.