c# - Why does adding double.epsilon to a value result in the same value, perfectly equal? -
i have unit test, testing boundaries:
[testmethod] [expectedexception(typeof(argumentoutofrangeexception))] public void createextent_invalidtop_shouldthrowargumentoutofrangeexception() { var invalidtop = 90.0 + double.epsilon; new extent(invalidtop, 0.0, 0.0, 0.0); } public static readonly double max_lat = 90.0; public extent(double top, double right, double bottom, double left) { if (top > geoconstants.max_lat) throw new argumentoutofrangeexception("top"); // not hit }
i thought i'd tip 90.0 on edge adding minimum possible positive double it, exception not thrown, idea why?
when debugging, see top coming in 90, when should 90.00000000.... something.
edit: should have thought bit harder, 90+double.epsilon
lose resolution. seems best way go bit shifting.
solution:
[testmethod] [expectedexception(typeof(argumentoutofrangeexception))] public void createextent_invalidtop_shouldthrowargumentoutofrangeexception() { var invalidtop = utility.incrementtiny(90); // 90.000000000000014 // var sameasepsilon = utility.incrementtiny(0); new extent(invalidtop, 0, 0, 0); } /// <summary> /// increment double-precision number smallest amount possible /// </summary> /// <param name="number">double-precision number</param> /// <returns>incremented number</returns> public static double incrementtiny(double number) { #region sanity checks if (double.isnan(number) || double.isinfinity(number)) throw new argumentoutofrangeexception("number"); #endregion var bits = bitconverter.doubletoint64bits(number); // if negative go opposite way if (number > 0) return bitconverter.int64bitstodouble(bits + 1); else if (number < 0) return bitconverter.int64bitstodouble(bits - 1); else return double.epsilon; } /// <summary> /// decrement double-precision number smallest amount possible /// </summary> /// <param name="number">double-precision number</param> /// <returns>decremented number</returns> public static double decrementtiny(double number) { #region sanity checks if (double.isnan(number) || double.isinfinity(number)) throw new argumentoutofrangeexception("number"); #endregion var bits = bitconverter.doubletoint64bits(number); // if negative go opposite way if (number > 0) return bitconverter.int64bitstodouble(bits - 1); else if (number < 0) return bitconverter.int64bitstodouble(bits + 1); else return 0 - double.epsilon; }
this job.
per the documentation of double.epsilon
:
the value of epsilon property reflects smallest positive
double
value significant in numeric operations or comparisons when value ofdouble
instance zero.
(emphasis mine.)
adding 90.0 not produce "the next smallest value after 90.0", yields 90.0 again.
Comments
Post a Comment