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

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

Жанры

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

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

Шрифт:

asdf - НЕ допустимое число одинарной точности.

Обсуждение

Шаблон функции

lexical_cast
преобразует значение из одного типа в другой. Он объявлен следующим образом.

template<typename Target, typename Source>

Target lexical_cast(Source arg)

Source
— это тип оригинальной переменной, a
Target
 — это тип переменной, в которую значение преобразуется. Таким образом, например, чтобы преобразовать из
string
в
int
,
вызов
lexical_cast
имеет вид:

int i = lexical_cast<int>(str); // str - это строка

lexical_cast
проводит анализ и пытается выполнить преобразование. Если преобразование невозможно, он выбрасывает исключение
bad_lexical_cast
. В примере 3.5 я только хочу проверить допустимость, и мне не требуется сохранять целевую переменную, так что если исключение не выбрасывается, я возвращаю
true
, а в противном случае —
false
.

В

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

int i = lexical_cast<int, string>(str);

Это означает то же самое, но указывать аргумент

string
не требуется, так как компилятор видит, что
str
— это
string
, и понимает, что от него требуется дальше.

Если вы собираетесь написать аналогичную функцию-обертку для проверки допустимости, возвращающую

true
и
false
, ее также можно написать как шаблон функции. В этом случае ее потребуется написать только один раз с использованием параметризованного типа, а различные версии будут генерироваться при каждом ее использовании с различными типами.

lexical_cast
также удобен для преобразования из одного числового типа в другой. Более подробно это обсуждается в рецепте 3.6.

Смотри также

Рецепт 3.6.

3.4. Сравнение чисел с плавающей точкой с ограниченной точностью

Проблема

Требуется сравнить значения с плавающей точкой, но при этом выполнить сравнение на равенство, больше чем или меньше чем с ограниченным количеством десятичных знаков. Например, требуется, чтобы 3.33333 и 3.33333333 считались при сравнении с точностью 0.0001 равными.

Решение

Напишите свои функции сравнения, которые принимают в качестве параметра ограничение точности сравнения. Пример 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, и, следовательно, как полагает машина, эти два числа не равны. Однако в некоторых приложениях может потребоваться, чтобы они считались равными.

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

70 Рублей

Кожевников Павел
1. 70 Рублей
Фантастика:
фэнтези
боевая фантастика
попаданцы
постапокалипсис
6.00
рейтинг книги
70 Рублей

Жатва душ. Остров мертвых

Сугралинов Данияр
Фантастика:
боевая фантастика
рпг
5.20
рейтинг книги
Жатва душ. Остров мертвых

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Как я строил магическую империю 6

Зубов Константин
6. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 6

Леди для короля. Оборотная сторона короны

Воронцова Александра
3. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Леди для короля. Оборотная сторона короны

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Газлайтер. Том 4

Володин Григорий
4. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 4

АллатРа

Новых Анастасия
Научно-образовательная:
психология
история
философия
обществознание
физика
6.25
рейтинг книги
АллатРа

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Дорога к счастью

Меллер Юлия Викторовна
Любовные романы:
любовно-фантастические романы
6.11
рейтинг книги
Дорога к счастью

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

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

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

Секретарша генерального

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
короткие любовные романы
8.46
рейтинг книги
Секретарша генерального