Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

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

Шрифт:

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

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
, объявленного в
<sstream>
, как показано в примере 3.7.

Пример 3.7. Лексический анализ числа в экспоненциальной форме

#include <iostream>

#include <sstream>

#include <string>

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
, который ведет себя как поток (что неудивительно). Он объявлен в
<sstring>
. Если требуется выполнить анализ
string
, содержащей число в экспоненциальной форме (см. также рецепт 3.2), то с этой работой прекрасно справится
stringstream
. Стандартные классы потоков уже «знают», как анализировать числа, так что не тратьте без острой необходимости время на повторную реализацию этой логики.

В примере 3.7 я написал простую функцию

sciToDub
, принимающую параметр типа
string
и возвращающую содержащийся в ней
double
, если он допустим. В
sciToDub
я использую
stringstream
следующим образом.

stringstream ss(str); // Конструирование из строки типа string

double d = 0;

ss >> d;

if (ss.fail) {

 string s = "Невозможно отформатировать ";

 s += str;

 s += " как число!";

 throw (s);

}

return (d);

Наиболее важной частью здесь является то, что все, что требуется сделать, — это использовать для чтения из строкового потока в

double
оператор сдвига вправо (
>>
), как это делается при чтении из
cin
.

Ну, это не совсем все, что требуется сделать. Если в

stringstream
записано значение, которое не может быть записано в переменную в правой части оператора
>>
, то для потока будет выставлен бит
fail
. Этот бит можно проверить с помощью функции-члена
fail
(на самом деле это функция-член
basic_ios
, который является родительским классом для
stringstream
). Кроме того, переменная справа от оператора
>>
в случае ошибки значения не меняет.

Однако с целью обобщения можно избежать написания отдельных версий

sciToDub
для типов
int
,
float
,
double
и чего-либо еще, что может потребоваться преобразовать, если написать шаблон функции. Рассмотрим такую новую версию.

template<typename T>

T strToNum(const string& str) {

 stringstream ss(str);

 T tmp;

 ss >> tmp;

 if (ss.fail) {

Поделиться:
Популярные книги

Жандарм 4

Семин Никита
4. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 4

Прорвемся, опера! Книга 2

Киров Никита
2. Опер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прорвемся, опера! Книга 2

Шайтан Иван 2

Тен Эдуард
2. Шайтан Иван
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Шайтан Иван 2

Архил...? 4

Кожевников Павел
4. Архил...?
Фантастика:
фэнтези
попаданцы
альтернативная история
5.50
рейтинг книги
Архил...? 4

Идеальный мир для Лекаря 6

Сапфир Олег
6. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 6

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Кротовский, не начинайте

Парсиев Дмитрий
2. РОС: Изнанка Империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, не начинайте

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Фиктивный брак

Завгородняя Анна Александровна
Фантастика:
фэнтези
6.71
рейтинг книги
Фиктивный брак

Николай I Освободитель. Книга 2

Савинков Андрей Николаевич
2. Николай I
Фантастика:
героическая фантастика
альтернативная история
5.00
рейтинг книги
Николай I Освободитель. Книга 2

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Барон устанавливает правила

Ренгач Евгений
6. Закон сильного
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Барон устанавливает правила

Отдельный танковый

Берг Александр Анатольевич
1. Антиблицкриг
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Отдельный танковый