Будьте осторожны с некоторыми ответами ...
1 - Вы можете легко представить любое число с 15 значащими цифрами в памяти с двойным. См. Википедия .
2 - Проблема связана с вычислением плавающих чисел, когда вы можете потерять некоторую точность. Я имею в виду, что после вычисления число типа .1 может стать чем-то вроде .1000000000000001 ==>. Когда вы делаете некоторые вычисления, результаты могут быть усечены, чтобы быть представленными в двойном. Это усечение приносит ошибку, которую вы можете получить.
3 - Чтобы избежать проблемы при сравнении двойных значений, люди вводят погрешность, часто называемую epsilon. Если 2 числа с плавающей запятой имеют только контекстную разницу в эпсилоне, то они считаются равными. Эпсилон никогда не бывает двойным. Эпсилон.
4 - эпсилон никогда не бывает двойным. Это всегда больше, чем это. Многие народы думают, что это двойной. Эпсилон, но они действительно не правы. Чтобы получить отличный ответ, пожалуйста, смотрите: Hans Passant answer . Эпсилон основан на вашем контексте, где он зависит от наибольшего числа, которое вы достигаете во время вычислений, и от количества вычислений, которые вы делаете (накапливается ошибка усечения). Epsilon - это наименьшее число, которое вы можете представить в своем контексте с 15 цифрами.
5 - это код, который я использую. Будьте осторожны, я использую свой эпсилон только для нескольких расчетов. В противном случае я умножаю свой эпсилон на 10 или 100.
6 - Как отмечает SvenL, возможно, мой эпсилон недостаточно велик. Предлагаю прочитать комментарий SvenL. Кроме того, возможно, "десятичная" может сделать работу для вашего случая?
public static class DoubleExtension
{
// ******************************************************************
// Base on Hans Passant Answer on:
// /1511260/double-epsilon-dlya-ravenstva-bolshe-menshe-menshe-ili-ravno-bolshe-ili-ravno
/// <summary>
/// Compare two double taking in account the double precision potential error.
/// Take care: truncation errors accumulate on calculation. More you do, more you should increase the epsilon.
public static bool AboutEquals(this double value1, double value2)
{
double epsilon = Math.Max(Math.Abs(value1), Math.Abs(value2)) * 1E-15;
return Math.Abs(value1 - value2) <= epsilon;
}
// ******************************************************************
// Base on Hans Passant Answer on:
// /1511260/double-epsilon-dlya-ravenstva-bolshe-menshe-menshe-ili-ravno-bolshe-ili-ravno
/// <summary>
/// Compare two double taking in account the double precision potential error.
/// Take care: truncation errors accumulate on calculation. More you do, more you should increase the epsilon.
/// You get really better performance when you can determine the contextual epsilon first.
/// </summary>
/// <param name="value1"></param>
/// <param name="value2"></param>
/// <param name="precalculatedContextualEpsilon"></param>
/// <returns></returns>
public static bool AboutEquals(this double value1, double value2, double precalculatedContextualEpsilon)
{
return Math.Abs(value1 - value2) <= precalculatedContextualEpsilon;
}
// ******************************************************************
public static double GetContextualEpsilon(this double biggestPossibleContextualValue)
{
return biggestPossibleContextualValue * 1E-15;
}
// ******************************************************************
/// <summary>
/// Mathlab equivalent
/// </summary>
/// <param name="dividend"></param>
/// <param name="divisor"></param>
/// <returns></returns>
public static double Mod(this double dividend, double divisor)
{
return dividend - System.Math.Floor(dividend / divisor) * divisor;
}
// ******************************************************************
}