如何确定整数是否适合变量?

时间:2014-10-24 07:05:58

标签: c++

int1_type x = ...;
int2_type y;

if ([check whether the current value of x will fit into y]) {
   y = x;
}

当它们的类型依赖于平台和/或模板特化时,是否有通用的方法来检查x的当前值是否适合y(例如,long x = 1; char y = x;)?

6 个答案:

答案 0 :(得分:1)

您的意图是分配它。基本类型的有损分配永远不会破坏您的程序:

template<typename T> int sign(T data) {
  return (data>=0) - (data<0);
}

template<typename T, typename K> bool test(T source, K target) {
  target = (K)source;
  return (source == target) && (sign(source)*sign(target)>=0);
}

简单地写

if (test(x,y)) {
 y = x;
}

答案 1 :(得分:1)

template<typename T, typename U>
bool will_fit(U u, T t = T())
{
    auto const Tmax = std::numeric_limits<T>::max();
    auto const Tmin = std::numeric_limits<T>::min();

    if (std::numeric_limits<U>::is_signed)
    {
        if (std::numeric_limits<T>::is_signed)
            return u >= (std::intmax_t)Tmin && u <= (std::intmax_t)Tmax;
        return u >= 0 && u <= (std::uintmax_t)Tmax;
    }
    else
        return u <= (std::uintmax_t)Tmax;
}

对于某些SFINAE tricks,其中一些运行时检查可以进行编译时检查,但如果性能有问题,我会留给您调查。

答案 2 :(得分:0)

如果您可以被限制为POD。

CHAR_BIT用于保存char中的位数。

我猜你可以做无符号类型:

if ((x >= 0) &&  (x < pow(2, CHAR_BIT * sizeof y))){
  y = x;
}

答案 3 :(得分:0)

表达式 y符合x 的当前值尚不清楚。

如果您的意思是 y的值适合x 的类型,那么您可以使用它:

if (sizeof(int2_type) <= sizeof(int1_type) || (int2_type)(int1_type)y == y)
{
    // the value of y fits into the type of x
}

答案 4 :(得分:0)

这个使用和检查值的范围和符号:

#include <limits>
#include <type_traits>

template<typename T> T max_for(T) { return std::numeric_limits<T>::max(); }
template<typename T> T min_for(T) { return std::numeric_limits<T>::min(); }
template<typename T> bool is_signed(T) { return std::is_signed<T>::value; }
template<typename T1, typename T2> bool same_sign(T1, T2) {
    return std::is_signed<T1>::value == std::is_signed<T2>::value; }

template <typename T1, typename T2>
bool fits(T1 src, T2 dst)
{
    auto valid_signed_to_unsigned =
        (is_signed(src) && !is_signed(dst) && src >= 0 && src <= ((max_for(dst) -1) / 2));

    auto valid_unsigned_to_sign =
        (!is_signed(src) && is_signed(dst) && src <= max_for(dst));

    auto valid_same =
        same_sign(src, dst) && src >= min_for(dst) && src <= max_for(dst);

    if (valid_signed_to_unsigned || valid_unsigned_to_sign || valid_same)
    {
        return true;
    }

    return false;
}

答案 5 :(得分:-2)

使用数字限制模板查找最大值,并使用辅助函数进行类型扣除:

#include <limits>

template<typename T> max_for(T) { return std::numeric_limits<T>::max(); }
template<typename T> min_for(T) { return std::numeric_limits<T>::min(); }

if (x >= min_for(y) && x <= max_for(y))
  y = x;   // type of y can accomodate the value x