using System;
public class Example
{
public static void Main()
{
double[] values = {
//12345678901234567
0.10000000000000001,
0.10000000000000002
};
Console.WriteLine("{0:r} = {1:r}: =:{2} ae:{3} re:{4} hmd1:{5} hmd0:{6}",
values[0], values[1],
values[0].Equals(values[1]),
AlmostEqual(values[0], values[1]),
ReallyEqual(values[0], values[1]),
HasMinimalDifference(values[0], values[1], 1),
HasMinimalDifference(values[0], values[1], 0));
Console.WriteLine();
}
public static bool AlmostEqual(double x, double y) {
double epsilon = Math.Max(Math.Abs(x), Math.Abs(y)) * 1E-15;
return Math.Abs(x - y) <= epsilon;
}
public static bool ReallyEqual(double x, double y) {
return (x == y);
}
public static bool HasMinimalDifference(double value1, double value2, int units) {
long lValue1 = BitConverter.DoubleToInt64Bits(value1);
long lValue2 = BitConverter.DoubleToInt64Bits(value2);
// If the signs are different, return false except for +0 and -0.
if ((lValue1 >> 63) != (lValue2 >> 63))
{
if (value1 == value2)
return true;
return false;
}
long diff = Math.Abs(lValue1 - lValue2);
Console.WriteLine("HMD: {0} {1} {2} {3}",
lValue1, lValue2, diff, units);
if (diff <= (long) units)
return true;
return false;
}
}
dXNpbmcgU3lzdGVtOwoKcHVibGljIGNsYXNzIEV4YW1wbGUKewogICBwdWJsaWMgc3RhdGljIHZvaWQgTWFpbigpCiAgIHsKICAgICAgZG91YmxlW10gdmFsdWVzID0geyAKICAgICAgCS8vMTIzNDU2Nzg5MDEyMzQ1NjcKICAgICAgICAwLjEwMDAwMDAwMDAwMDAwMDAxLAogICAgICAgIDAuMTAwMDAwMDAwMDAwMDAwMDIKICAgICAgICB9OwoKICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoInswOnJ9ID0gezE6cn06ID06ezJ9IGFlOnszfSByZTp7NH0gaG1kMTp7NX0gaG1kMDp7Nn0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzBdLCB2YWx1ZXNbMV0sICAKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzBdLkVxdWFscyh2YWx1ZXNbMV0pLAogICAgICAgICAgICAgICAgICAgICAgICBBbG1vc3RFcXVhbCh2YWx1ZXNbMF0sIHZhbHVlc1sxXSksCiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWxseUVxdWFsKHZhbHVlc1swXSwgdmFsdWVzWzFdKSwKICAgICAgICAgICAgICAgICAgICAgICAgSGFzTWluaW1hbERpZmZlcmVuY2UodmFsdWVzWzBdLCB2YWx1ZXNbMV0sIDEpLAogICAgICAgICAgICAgICAgICAgICAgICBIYXNNaW5pbWFsRGlmZmVyZW5jZSh2YWx1ZXNbMF0sIHZhbHVlc1sxXSwgMCkpOwogICAgICBDb25zb2xlLldyaXRlTGluZSgpOwogICB9CiAgIAogICBwdWJsaWMgc3RhdGljIGJvb2wgQWxtb3N0RXF1YWwoZG91YmxlIHgsIGRvdWJsZSB5KSB7CiAgICAgIGRvdWJsZSBlcHNpbG9uID0gTWF0aC5NYXgoTWF0aC5BYnMoeCksIE1hdGguQWJzKHkpKSAqIDFFLTE1OwogICAgICByZXR1cm4gTWF0aC5BYnMoeCAtIHkpIDw9IGVwc2lsb247CiAgIH0KCiAgIHB1YmxpYyBzdGF0aWMgYm9vbCBSZWFsbHlFcXVhbChkb3VibGUgeCwgZG91YmxlIHkpIHsKICAgCSAgcmV0dXJuICh4ID09IHkpOwogICB9CiAgIAogICBwdWJsaWMgc3RhdGljIGJvb2wgSGFzTWluaW1hbERpZmZlcmVuY2UoZG91YmxlIHZhbHVlMSwgZG91YmxlIHZhbHVlMiwgaW50IHVuaXRzKSB7CiAgICAgIGxvbmcgbFZhbHVlMSA9IEJpdENvbnZlcnRlci5Eb3VibGVUb0ludDY0Qml0cyh2YWx1ZTEpOwogICAgICBsb25nIGxWYWx1ZTIgPSBCaXRDb252ZXJ0ZXIuRG91YmxlVG9JbnQ2NEJpdHModmFsdWUyKTsKCiAgICAgIC8vIElmIHRoZSBzaWducyBhcmUgZGlmZmVyZW50LCByZXR1cm4gZmFsc2UgZXhjZXB0IGZvciArMCBhbmQgLTAuIAogICAgICBpZiAoKGxWYWx1ZTEgPj4gNjMpICE9IChsVmFsdWUyID4+IDYzKSkKICAgICAgewogICAgICAgICBpZiAodmFsdWUxID09IHZhbHVlMikKICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KCiAgICAgIGxvbmcgZGlmZiA9IE1hdGguQWJzKGxWYWx1ZTEgLSBsVmFsdWUyKTsKICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoIkhNRDogezB9IHsxfSB7Mn0gezN9IiwKICAgICAgICAgICAgICAgICAgICAgICAgbFZhbHVlMSwgbFZhbHVlMiwgZGlmZiwgdW5pdHMpOwoKICAgICAgaWYgKGRpZmYgPD0gKGxvbmcpIHVuaXRzKQogICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgIHJldHVybiBmYWxzZTsKICAgfQoKfQoKCg==