// Новое равенство. Проходит так, как требуется в научном приложении.
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
Чтобы добиться этого, надо написать собственные функции сравнения чисел с двойной точностью: doubleLess
doubleEquals
и doubleGreater
, каждая из которых принимает в качестве параметров два значения типа double
. Кроме того, doubleLess
и doubleGreater
имеют дополнительный параметр, который при его равенстве true
приводит к тому, что эти функции ведут себя как «Чтобы заставить эти функции учитывать точность, рассмотрим функцию doubleEquals
epsilon
. (В качестве epsilon
пример использует значение 0.0001.) Если это так, то функция возвращает значение true, что означает, что значения одинаковы. Таким образом, равными окажутся значения 0.3333, 0.33333, 0.333333, 0.33333333333 и 0.33333323438.Чтобы выполнить операцию «
doubleEquals
. Если так, то при наличии теста на равенство верните true
, а в противном случае — false
. В противном случае выполните прямое сравнение.3.5. Лексический анализ строки, содержащей число в экспоненциальной форме
Имеется строка, содержащая число в экспоненциальной форме, и требуется сохранить значение числа в переменной типа double
Наиболее простым способом анализа числа в экспоненциальной форме является использование встроенного в библиотеку C++ класса stringstream
, как показано в примере 3.7.#include
#include
#include
using namespace std;
double sciToDub(const strings str) {
stringstream ss(str);
double d = 0;
ss >> d;
if (ss.fail()) {
string s = "Невозможно отформатировать ";
s += str;
s += " как число!";
throw (s);
}
return (d);
}
int main() {
try {
cout << sciToDub("1.234e5") << endl;
cout << sciToDub("6.02e-2") << endl;
cout << sciToDub("asdf") << endl;
} catch (string& e) {
cerr << "Ошибка: " << e << endl;
}
}
Далее показан вывод этого кода.
123400
0.0602
Ошибка: невозможно отформатировать asd как число!
Класс stringstream
string
, который ведет себя как поток (что неудивительно). Он объявлен в
. Если требуется выполнить анализ string
, содержащей число в экспоненциальной форме (см. также рецепт 3.2), то с этой работой прекрасно справится stringstream
. Стандартные классы потоков уже «знают», как анализировать числа, так что не тратьте без острой необходимости время на повторную реализацию этой логики.