C++. Сборник рецептов - [55]

Шрифт
Интервал

> else

>  cout << s << " - HE допустимое число двойной точности." << endl;

> if (isValid(s))

>  cout << s << " - допустимое число одинарной точности." << endl;

> else

>  cout << s << " - HE допустимое число одинарной точности " << endl;

>}


>int main() {

> test("12345");

> test("1.23456");

> test("-1.23456");

> test(" - 1.23456");

> test("+1.23456");

> test(" 1.23456 ");

> test("asdf");

>}

Вот вывод этого примера.

>12345 - допустимое целое число.

>12345 - допустимое число двойной точности.

>12345 - допустимое число одинарной точности.

>1.23456 - НЕ допустимое целое число.

>1.23456 - допустимое число двойной точности.

>1.23456 - допустимое число одинарной точности.

>-1.23456 - НЕ допустимое целое число.

>-1.23456 - допустимое число двойной точности.

>-1.23456 - допустимое число одинарной точности.

>- 1.23456 - НЕ допустимое целое число.

>- 1 23466 - НЕ допустимое число двойной точности.

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

>+1.23456 - НЕ допустимое целое число.

>+1.23456 - допустимое число двойной точности.

>+1.23456 - допустимое число одинарной точности.

> 1.23456 - НЕ допустимое целое число.

> 1.23456 - НЕ допустимое число двойной точности.

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

>asdf - НЕ допустимое целое число.

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

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

Обсуждение

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

>template

>Target lexical_cast(Source arg)

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

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

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

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

>int i = lexical_cast(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

>#include // для 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;

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


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.