1.23456 - НЕ допустимое число двойной точности.
1.23456 - НЕ допустимое число одинарной точности.
asdf - НЕ допустимое целое число.
asdf - НЕ допустимое число двойной точности.
asdf - НЕ допустимое число одинарной точности.
Шаблон функции lexical_cast
template
Target lexical_cast(Source arg)
Source
Target
— это тип переменной, в которую значение преобразуется. Таким образом, например, чтобы преобразовать из string
в int
, вызов lexical_cast
имеет вид:int i = lexical_cast
lexical_cast
bad_lexical_cast
. В примере 3.5 я только хочу проверить допустимость, и мне не требуется сохранять целевую переменную, так что если исключение не выбрасывается, я возвращаю true
, а в противном случае — false
.В lexical_cast
lexical_cast
, как в предыдущем фрагменте кода, можно сделать так.int i = lexical_cast
Это означает то же самое, но указывать аргумент string
str
— это string
, и понимает, что от него требуется дальше.Если вы собираетесь написать аналогичную функцию-обертку для проверки допустимости, возвращающую true
false
, ее также можно написать как шаблон функции. В этом случае ее потребуется написать только один раз с использованием параметризованного типа, а различные версии будут генерироваться при каждом ее использовании с различными типами.lexical_cast
Рецепт 3.6.
3.4. Сравнение чисел с плавающей точкой с ограниченной точностью
Требуется сравнить значения с плавающей точкой, но при этом выполнить сравнение на равенство, больше чем или меньше чем с ограниченным количеством десятичных знаков. Например, требуется, чтобы 3.33333 и 3.33333333 считались при сравнении с точностью 0.0001 равными.
Напишите свои функции сравнения, которые принимают в качестве параметра ограничение точности сравнения. Пример 3.6 показывает основную методику, используемую в такой функции сравнения.
#include
#include
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;