сравнение двойных значений в переполнении стека

У меня есть следующий код для двойного сравнения. Почему я не равняюсь, когда я выполняю?

#include <iostream>
#include <cmath>
#include <limits>

bool AreDoubleSame(double dFirstVal, double dSecondVal)
{
return std::fabs(dFirstVal - dSecondVal) < std::numeric_limits<double>::epsilon();
}int main()
{
double dFirstDouble = 11.304;
double dSecondDouble = 11.3043;

if(AreDoubleSame(dFirstDouble , dSecondDouble ) )
{
std::cout << "equal" << std::endl;
}
else
{
std::cout << "not equal" << std::endl;
}
}

1

Решение

Эпсилон на 2 пары 2.22045e-016

По определению, эпсилон — это разница между 1 и наименьшим значением, большим 1, которое
представляемый для типа данных.

Они отличаются более чем, и, следовательно, он возвращает ложь

(Ссылка)

13

Другие решения

Они не равны (в зависимости от вашей функции), потому что они отличаются более чем на epsilon,

Эпсилон определяется какМашинный эпсилон (разница между 1 и наименьшим значением больше 1, которое представимо)» — источник http://www.cplusplus.com/reference/std/limits/numeric_limits/. Это примерно 2.22045e-016 (источник http://msdn.microsoft.com/en-us/library/6x7575x3(v=vs.71).aspx)

Если вы хотите изменить коэффициент помадки, сравните его с другим небольшим двойным числом, например:

bool AreDoubleSame(double dFirstVal, double dSecondVal)
{
return std::fabs(dFirstVal - dSecondVal) < 1E-3;
}
6

Разница между вашими двумя двойниками составляет 0,0003. std :: numeric_limits :: epsilon () намного меньше, чем это.

5

epsilon() только разница между 1.0 и следующее значение, представимое после 1.0реальный мин. Функция библиотеки std::nextafter может использоваться для масштабирования теста точности равенства для чисел любой величины.

Например, используя std::nextafter тестировать double равенство, проверяя, что б является <= следующее число ниже, чем && > = следующий номер выше чем:

bool nearly_equal(double a, double b)
{
return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
&& std::nextafter(a, std::numeric_limits<double>::max()) >= b;
}

Это, конечно, будет только true если битовые шаблоны для & б одинаковы. Так что это неэффективный способ (неправильного) наивного прямого сравнения a == b, поэтому:

Чтобы проверить два double для равенства внутри некоторого фактора, масштабируемого до представимого различия, вы можете использовать:

bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
{
double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

return min_a <= b && max_a >= b;
}

Конечно, для работы с плавающей запятой потребуется анализ точности вычислений, чтобы определить, как возникают ошибки представления, чтобы определить правильный минимальный коэффициент.

3

Эпсилон намного меньше 0,0003, поэтому они явно не равны.

Если вы хотите увидеть, где это работает, проверьте http://ideone.com/blcmB

2