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

ЖАНРЫ

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

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

Шрифт:

 return(res);

}

void test(const string& s) {

 if (isValid<int>(s))

cout << s << " - допустимое целое число." << endl;

 else

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

 if (isValid<double>(s))

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

 else

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

 if (isValid<float>(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<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,

Поделиться с друзьями: