Достаточный для хранения 2x числа тип

331
26 февраля 2017, 08:50

У меня есть число. Как получить тип, который может хранить это число, умноженное на 2, если число имеет не "максимальный" тип? Например, число i типа __int32, тогда 2*i всегда можем хранить в __int64. Как узнать, что нужен __int64?

Answer 1

Ну навскидку можно просто вручную создать (платформенно-зависимый) маппинг размеров типов на следующий по размеру тип

template <size_t N> struct next_type_impl;
template <> next_type_impl<8> {
  // Предполагая 16-битный `short`
  typedef short signed_type;
  typedef unsigned short unsigned_type;
};
template <> next_type_impl<16> {
  // Предполагая 32-битный `int`
  typedef int signed_type;
  typedef unsigned unsigned_type;
};
// И т.д.
template <typename T> next_type {
  typedef typename next_type_impl<sizeof(T)>::signed_type signed_type;
  typedef typename next_type_impl<sizeof(T)>::unsigned_type unsigned_type;
};

А далее в коде

next_type<decltype(i)>::signed_type larger_i;

Все это можно реализовать элегантнее и гибче, но примерная идея такова.

Например, один раз задав руками последовательность целочисленных типов, можно уже автоматически платформенно-независимо выбирать тип большего размера, если он существует

#include <type_traits>
#include <iostream>
template <typename T> struct next_int { typedef T type; };
template <> struct next_int<signed char> { typedef short type; };
template <> struct next_int<short> { typedef int type; };
template <> struct next_int<int> { typedef long type; };
template <> struct next_int<long> { typedef long long type; };
/**********/
template <typename T> struct next_larger_int;
template <typename T, bool stop = false> struct next_larger_int_cond
{
  typedef typename next_larger_int<typename next_int<T>::type>::type type;
};
template <typename T> struct next_larger_int_cond<T, true>
{
  typedef T type;
};
template <typename T> struct next_larger_int
{
  typedef typename next_int<T>::type next;
  typedef typename next_larger_int_cond<next, (sizeof(next) > sizeof(T)) || std::is_same<T, next>::value>::type type;
};

int main()
{
  std::cout <<
    sizeof(next_larger_int<signed char>::type) << std::endl <<
    sizeof(next_larger_int<short>::type) << std::endl <<
    sizeof(next_larger_int<int>::type) << std::endl <<
    sizeof(next_larger_int<long>::type) << std::endl <<
    sizeof(next_larger_int<long long>::type) << std::endl;
}
Answer 2

Вообще-то в C++ ничего не говорится о конкретных размерах типов. Так что int может оказаться и таким же, как __int64.

Разве что смотрите в <cstdint> типы с точными размерами.

READ ALSO
Матрица как вектор векторов

Матрица как вектор векторов

Вот тут - http://rustackoverflow

370
Не могу назначить StandardGestures динамически

Не могу назначить StandardGestures динамически

В чем ошибка? не понимаю синтаксиса

325
Вызов методов класса через указатель на функцию

Вызов методов класса через указатель на функцию

Хочу реализовать возможность передавать в качестве аргумента функции указатель на метод разных классов

413
Вставка в unordered_map/set

Вставка в unordered_map/set

Если количество корзин в unordered map/set равно количеству элементов для вставки, гарантировано ли константное время вставки каждого элемента...

313