реклама на сайте
подробности

 
 
> Получение предельно допустимых значений переменной, во время работы программы на случай переопределения типа
Dimoza
сообщение Apr 1 2013, 12:05
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 120
Регистрация: 21-08-06
Из: СПб
Пользователь №: 19 701



Здравствуйте. Подскажите, возможно ли в С/С++ красиво реализовать следующее:

Есть некая переменная, которой во время работы программы хочется присвоить максимально (минимально) допустимое значение. Если мы например решили, что переменная типа signed char, то ясное дело, можно просто присваивать +127 или -128. Но если вдруг по каким либо причинам тип изменили на signed int, то нужны уже другие значения, +32767 и -32768. Хорошо если при этом не забыли пробежать по коду и везде поменять. А если забыли? Как бы это покрасивше автоматизировать? Вроде бы корректный путь написать что-то вроде:
CODE
signed int AD_Umax;
AD_Umax = (1<<(sizeof(AD_Umax)*8-1))-1;

Но компилятор в этом случае выдаёт предупреждение о том, что "превышено максимально допустимое значение", что логично: в процессе вычисления есть промежуточная величина, выходящая за допустимые для данного типа пределы.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
neiver
сообщение Apr 5 2013, 10:06
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Я для определения предельных значений типов пользуюсь такими С++ шаблонами:
Код
template<class T, T IntegralTypeCheck=T(0)>
struct IsSigned
{
    enum{value = T(-1) < T(0)};
};

template<class T>
struct MinValue
{
    static const T value = IsSigned<T>::value ? ( T(1) << (sizeof(T)*8 - 1)) : 0;
};

template<class T>
struct MaxValue
{
    static const T value = ~MinValue<T>::value;
};

Работает, естественно, на платформах где в байте 8 бит и с отрицательными числами в дополнительном коде.
Эти шаблоны несложно на макросы переписать, если нужно.
А пользоваться ими примерно так:
Код
    cout << "Min int =\t" <<  MinValue<int>::value << "\tMax int = " << MaxValue<int>::value << endl;
    cout << "Min unsigned =\t" <<  MinValue<unsigned>::value << "\tMax unsigned = " << MaxValue<unsigned>::value << endl;
    cout << "Min long long =\t" <<  MinValue<long long>::value << "\tMax long long = " << MaxValue<long long>::value << endl;
    cout << "Min char =\t" <<  MinValue<char>::value << "\tMax char = " << MaxValue<char>::value << endl;
    cout << "Min short =\t" <<  MinValue<short>::value << "\tMax short = " << MaxValue<short>::value << endl;
    cout << "Min unsigned short =\t" <<  MinValue<unsigned short>::value << "\tMax unsigned short = " << MaxValue<unsigned short>::value << endl;


Сообщение отредактировал neiver - Apr 5 2013, 10:11
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 5 2013, 10:33
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(neiver @ Apr 5 2013, 14:06) *
Эти шаблоны несложно на макросы переписать, если нужно.
А вы попробуйте! Да так чтобы без привязки к gcc...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
neiver
сообщение Apr 5 2013, 10:54
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(demiurg_spb @ Apr 5 2013, 14:33) *
А вы попробуйте! Да так чтобы без привязки к gcc...

Попробовал. Получилось. Работает.
Код
#define __IS_SIGNED(TYPE) ((TYPE)(-1) < (TYPE)(0))
#define IS_SIGNED(TYPE) __IS_SIGNED(TYPE)
#define __MIN_VALUE(TYPE) (IS_SIGNED(TYPE) ? ( (TYPE)(1) << (sizeof(TYPE)*8 - 1)) : 0)
#define MIN_VALUE(TYPE) __MIN_VALUE(TYPE)
#define __MAX_VALUE(TYPE) (~MIN_VALUE(TYPE))
#define MAX_VALUE(TYPE) __MAX_VALUE(TYPE)

Можно даже вот так писать:
Код
#define MY_TYPE int
enum Foo
{
    Max = MAX_VALUE(MY_TYPE)
};

Но мне с шаблонами удобнее.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Apr 5 2013, 11:06
Сообщение #5


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(neiver @ Apr 5 2013, 14:54) *
Это немного не то...
Вы аргументом передаёте тип, а нужно экземпляр этого типа...
Но и так тоже можно выкрутиться (через typedef).
А вообще очень лаконично сделано!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 10:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01391 секунд с 7
ELECTRONIX ©2004-2016