Только знания, что это может привести к проблемам, не достаточно. Вы можете быть ограничены жесткими требованиями по объему и не захотите использовать четыре байта для long
short
(если ваша платформа на самом деле использует такие размеры, что очень распространено, но не гарантируется). Из-за ограничений по объему может возникнуть желание попробовать хранить значения в наименьших возможных типах. Если вы любите приключения, но вам нужна страховка, для перехвата потерь данных при работе программы используйте numeric_cast
из Boost.Синтаксис numeric_cast
template
inline Target numeric_cast(Source arg)
Если вы уже прочли рецепты 3.1 и 3.3, он аналогичен lexical_cast
Target
и Source
, — которые представляют типы оригинального и результирующего значений. Так как это шаблон функции, компилятор может догадаться о типе аргумента Source
, так что требуется указать только Target
, как здесь.int i = 32767;
short s = numeric_cast
short
Target
. Компилятор догадывается, что Source
имеет тип int
потому, что i
имеет тип int
.В этом случае я впихиваю int
short
. В моей системе (Windows XP) int имеет длину четыре байта, a short
— два. short
имеет знак, это означает, что для представления числа в нем используется 15 бит и, следовательно, максимальным допустимым положительным значением для него является 32 767. Приведенный выше фрагмент кода работает молча, но когда я увеличиваю i
на единицу, она выходит за диапазон short
.s = numeric_cast
Вы уже догадались, что выбрасывается исключение bad_numeric_cast
numeric
_cast также перехватывает потери знака, возникающие при присвоении отрицательного значения со знаком типу без знака.Но numeric_cast
numeric_cast
в этой ситуации не спасает, так что не думайте, что он сможет уберечь вас от всех рискованных предприятий. Например, рассмотрим такой фрагмент кода из примера 3.8:double a = 3.14;
int i = numeric_cast
Здесь не будет выброшено никаких исключений. Но это произойдет, если попробовать такое:
double d = -3.14;
unsigned int ui = numeric_cast
Потому что, несмотря на то что происходит потеря всего, что находится справа от десятичной точки, происходит потеря знака, а это очень плохо.
Рецепты 3.1 и 3.3.
3.7. Получение минимального и максимального значений числового типа
Требуется узнать наибольшее и наименьшее значения, представляемые на данной платформе числовым типом, таким как int
double
.Чтобы среди прочего получить максимальное и минимальное допустимые значения числового типа, используйте шаблон класса numeric_limits
(см. пример 3.9).#include
#include
using namespace std;
template
void showMinMax() {
cout << "min: " << numeric_limits
cout << "max: " << numeric_limits
cout << endl;
}
int main() {
cout << "short:" << endl;
showMinMax
cout << "int:" << endl;
showMinMax
cout << "long:" << endl;
showMinMax
cout << "float:" << endl;
showMinMax
cout << "double:" << endl;
showMinMax
cout << "long double:" << endl;
showMinMax
cout << "unsigned short:" << endl;
showMinMax
cout << "unsigned int:" << endl;
showMinMax
cout << "unsigned long:" << endl;
showMinMax
}
Вот что я получил в 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