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

ЖАНРЫ

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

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

Шрифт:

Синтаксис

numeric_cast
очень прост. Это шаблон функции, объявленный следующим образом.

template<typename Target, typename Source>

inline Target numeric_cast(Source arg)

Если вы уже прочли рецепты 3.1 и 3.3, он аналогичен

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

int i = 32767;

short s = numeric_cast<short>(i);

short
— это аргумент, передаваемый в шаблон как параметр
Target
. Компилятор догадывается, что
Source
имеет тип
int
потому, что
i
имеет тип
int
.

В этом случае я впихиваю

int
в
short
. В моей системе (Windows XP) int имеет длину четыре байта, a
short
— два.
short
имеет знак, это означает, что для представления числа в нем используется 15 бит и, следовательно, максимальным допустимым положительным значением для него является 32 767. Приведенный выше фрагмент кода работает молча, но когда я увеличиваю
i
на единицу, она выходит за диапазон
short
.

s = numeric_cast<short>(i); // Ох!

Вы уже догадались, что выбрасывается исключение

bad_numeric_cast
. Смотри остальную часть примера 3.8:
numeric
_cast также перехватывает потери знака, возникающие при присвоении отрицательного значения со знаком типу без знака.

Но

numeric_cast
не решает всех проблем. Если попытаться поместить значение с плавающей точкой в тип без плавающей точки, то будет потеряно все, что находится справа от десятичной точки, так?
numeric_cast
в этой ситуации не спасает, так что не думайте, что он сможет уберечь вас от всех рискованных предприятий. Например, рассмотрим такой фрагмент кода из примера 3.8:

double a = 3.14;

int i = numeric_cast<int>(d); // Ох!

Здесь не будет выброшено никаких исключений. Но это произойдет, если попробовать такое:

double d = -3.14;

unsigned int ui = numeric_cast<unsigned int>(d);

Потому что, несмотря на то что происходит потеря всего, что находится справа от десятичной точки, происходит потеря знака, а это очень плохо.

Смотри также

Рецепты 3.1 и 3.3.

3.7. Получение минимального и максимального значений числового типа

Проблема

Требуется узнать наибольшее и наименьшее значения, представляемые на данной платформе числовым типом, таким как

int
или
double
.

Решение

Чтобы среди прочего получить максимальное и минимальное допустимые значения числового типа, используйте шаблон класса

numeric_limits
из заголовочного файла
<limits>
(см. пример 3.9).

Пример 3.9. Получение числовых ограничений

#include <iostream>

#include <limits>

using namespace std;

template<typename T>

void showMinMax {

 cout << "min: " << numeric_limits<T>::min << endl;

 cout << "max: " << numeric_limits<T>::max << endl;

 cout << endl;

}

int main {

 cout << "short:" << endl;

 showMinMax<short>;

 cout << "int:" << endl;

 showMinMax<int>;

 cout << "long:" << endl;

 showMinMax<long>;

 cout << "float:" << endl;

 showMinMax<float>;

 cout << "double:" << endl;

 showMinMax<double>;

 cout << "long double:" << endl;

 showMinMax<long double>;

 cout << "unsigned short:" << endl;

 showMinMax<unsigned short>;

 cout << "unsigned int:" << endl;

 showMinMax<unsigned int>;

 cout << "unsigned long:" << endl;

 showMinMax<unsigned long>;

}

Вот

что я получил в Windows XP, используя Visual C++ 7.1.

short:

min: -32768

max: 32767

int:

min: -2147483648

max: 2147483647

long:

min -2147483648

max 2147483647

float:

min: 1.17549e-038

max: 3.40282e-038

double:

min: 2.22507e-308

max: 1.79769e+308

long double:

min: 2.22507e-308

max: 1.79769e+308

unsigned short:

min: 0

max: 65535

unsigned int:

min: 0

max: 4294967295

unsigned long:

min: 0

max: 4294967295

Обсуждение

Пример 3.9 показывает простой пример получения минимального и максимального значений встроенных числовых типов. Шаблон класса

numeric_limits
имеет специализации для всех встроенных типов, включая как числовые, так и нечисловые типы. Стандарт требует, чтобы все типы, которые я использовал в примере 3.9, а также перечисленные далее, имели свою специализацию
numeric_limits
.

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