Ограничения типов переменных C++

вот довольно простой вопрос (я думаю), есть ли метод библиотеки STL, который предоставляет предел типа переменной (Эл.г-целое число) ? Я знаю, что эти пределы различаются на разных компьютерах, но должен быть способ получить их через метод, верно?

и было бы действительно сложно написать метод для вычисления предела типа переменной?

Мне просто любопытно! :)

спасибо ;).

4 ответов


использовать std::numeric_limits:

// numeric_limits example
// from the page I linked
#include <iostream>
#include <limits>
using namespace std;

int main () {
  cout << boolalpha;
  cout << "Minimum value for int: " << numeric_limits<int>::min() << endl;
  cout << "Maximum value for int: " << numeric_limits<int>::max() << endl;
  cout << "int is signed: " << numeric_limits<int>::is_signed << endl;
  cout << "Non-sign bits in int: " << numeric_limits<int>::digits << endl;
  cout << "int has infinity: " << numeric_limits<int>::has_infinity << endl;
  return 0;
}

Я вижу, что 'правильный' ответ уже дан: использовать <limits> и пусть волшебство произойдет. Я нахожу этот ответ неудовлетворительным, так как вопрос:

было бы действительно сложно написать метод для вычисления предела типа переменной?

ответ: легко для целочисленных типов, трудно для типов float. Существует 3 основных типа алгоритмов, которые вам понадобятся для этого. подписано, без подписи и с плавающей запятой. каждый из них имеет различные алгоритм для того, как вы получаете min и max, а фактический код включает в себя некоторое битовое скручивание, и в случае с плавающей точкой вам нужно выполнить цикл, если у вас нет известного целочисленного типа, который имеет тот же размер, что и тип float.

Итак, вот он.

без знака легко. min-это когда все биты равны 0, max - когда все биты равны 1.

const unsigned type unsigned_type_min = (unsigned type)0;    
const unsigned type unsigned_type_max = ~(unsigned type)0;

для signed min-это когда бит знака установлен, но все остальные биты являются нулями, max-когда все биты кроме знаковый бит установлен. без знания размера типа, мы не знаем, где знак бит, но мы можем использовать некоторые трюки бит, чтобы заставить это работать.

const signed type signed_type_max = (signed type)(unsigned_type_max >> 1);
const signed type signed_type_min = (signed type)(~(signed_type_max));

для плавающей точки есть 4 предела, хотя знать только положительные пределы достаточно, отрицательные пределы - это просто знак перевернутые положительные пределы. Существует потенциально много способов представления чисел с плавающей запятой, но для тех, кто использует двоичную (а не базовую 10) плавающую точку, почти все используют Представления стандарта IEEE.

для поплавков IEEE наименьшее положительное значение с плавающей запятой - это когда низкий бит экспоненты равен 1, а все остальные биты равны 0. Наибольшее отрицательное значение с плавающей запятой является побитовым обратным этому. Однако без целочисленного типа, который, как известно, имеет тот же размер, что и данный тип с плавающей запятой, нет никакого способа выполнить эту битовую манипуляцию, кроме выполнения цикла. если у вас есть целочисленный тип, который, как вы знаете, имеет тот же размер, что и ваш плавающий тип точки, вы можете сделать это в одну операцию.

const float_type get_float_type_smallest() {
   const float_type float_1 = (float_type)1.0;
   const float_type float_2 = (float_type)0.5;
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ((byte*)&float_1)[ii] ^ ((byte*)&float_2)[ii];
   return u.fl;
   }

const float_type get_float_type_largest() {
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   u.fl = get_float_type_smallest();
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ~u.ab[ii];
   return -u.fl; // Need to re-invert the sign bit.
   }

(связано с C, но я думаю, что это также относится к c++)

вы также можете попробовать"запрос", который является скриптом, который может воссоздать пределы.h для вашего компилятора. Цитата из домашней страницы projetc:

Это программа, которая определяет многие свойства компилятора C и машина, на которой он работает, например минимальная и максимальная [ООН]подпись char / int / long, много свойств float / [long] double и так далее.

Как вариант он производит ANSI C плыть.h И пределы.H-файлы.

в качестве дополнительной опции, он даже проверяет что компилятор читает заголовок файлы правильно.

Это хороший тестовый случай для компиляторов, так как он упражняет их со многими предельные значения, такие как минимум и максимальные числа с плавающей точкой.


#include <limits>

std::numeric_limits<type>::max() // min() etc