Private-Bookers
C++. Сборник рецептов
вернуться

Когсуэлл Джефф

Шрифт:
Решение

Напишите свои функции сравнения, которые принимают в качестве параметра ограничение точности сравнения. Пример 3.6 показывает основную методику, используемую в такой функции сравнения.

Пример 3.6. Сравнение чисел с плавающей точкой

#include <iostream>

#include <cmath> // для fabs

using namespace std;

bool doubleEquals(double left, double right, double epsilon) {

 return (fabs(left - right) < epsilon);

}

bool doubleLess(double left, double right, double epsilon,

 bool orequal = false) {

 if (fabs(left - right) < epsilon) {

// В рамках epsilon, так что считаются равными

return (orequal);

 }

 return (left < right);

}

bool doubleGreater(double left, double right, double epsilon,

 bool orequal = false) {

 if (fabs(left - right) < epsilon) {

// В рамках epsilon, так что считаются равными

 return (orequal);

 }

 return (left > right);

}

int main {

 double first = 0.33333333;

 double second = 1.0 / 3.0;

 cout << first << endl;

 cout << second << endl;

 // Тест на прямое равенство. Не проходит тогда, когда должно проходить.

 // (boolalpha печатает булевы значения как "true" или "false")

 cout << boolalpha << (first == second) << endl;

 // Новое равенство. Проходит так, как требуется в научном приложении.

 cout << doubleEquals(first, second, .0001) << endl;

 // Новое меньше чем

 cout << doubleLess(first, second, .0001) << endl;

 // Новое больше чем

 cout << doubleGreater(first, second, .0001) << endl;

 // Новое меньше чем или равно

 cout << doubleLess(first, second, .0001, true) << endl;

 // Новое больше чем или равно

 cout << doubleGreater(first, second, .0001, true) << endl;

}

Далее показан вывод этого примера.

0.333333

0.333333

false

true

false

false

true

true

Обсуждение

Код примера 3.6 начинается с двух значений — 0.33333333 и того, что компьютер получает в результате деления 1.0 / 3.0. Он с помощью форматирования по умолчанию

cout
печатает эти два значения. Они кажутся одинаковыми и равными 0.333333. Однако при сравнении этих двух значений они оказываются различными. Значение 1.0 / 3.0 имеет больше значащих цифр, чем 0.33333333, и, следовательно, как полагает машина, эти два числа не равны. Однако в некоторых приложениях может потребоваться, чтобы они считались равными.

Чтобы добиться этого, надо написать собственные функции сравнения чисел с двойной точностью:

doubleLess
,
doubleEquals
и
doubleGreater
, каждая из которых принимает в качестве параметров два значения типа
double
. Кроме того,
doubleLess
и
doubleGreater
имеют дополнительный параметр, который при его равенстве
true
приводит к тому, что эти функции ведут себя как «меньше или равно» и «больше или равно» соответственно.

Чтобы заставить эти функции учитывать точность, рассмотрим функцию

doubleEquals
. Вместо того чтобы проверять на равенство, эта функция проверяет, находится ли разность двух чисел в указанном пользователем диапазоне
epsilon
. (В качестве
epsilon
пример использует значение 0.0001.) Если это так, то функция возвращает значение true, что означает, что значения одинаковы. Таким образом, равными окажутся значения 0.3333, 0.33333, 0.333333, 0.33333333333 и 0.33333323438.

  • Читать дальше
  • 1
  • ...
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • ...

Private-Bookers - русскоязычная библиотека для чтения онлайн. Здесь удобно открывать книги с телефона и ПК, возвращаться к сохраненной странице и держать любимые произведения под рукой. Материалы добавляются пользователями; если считаете, что ваши права нарушены, воспользуйтесь формой обратной связи.

Полезные ссылки

  • Моя полка