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

How to determine if an integer will fit a variable?

本文关键字:变量 是否 何确定 整数      更新时间:2023-10-16
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;(当它们的类型取决于平台和/或模板专业化时?

你的目的是分配它。基本类型的有损赋值永远不会损坏您的程序,因此:

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;
}
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 技巧,其中一些运行时检查可以变成编译时检查,但如果性能有问题,我会留给你调查。

如果您可以限制为 POD。

有一个CHAR_BIT,它保存了一个字符中有多少位。

我想你可以为无符号类型做:

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

表达式 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
}

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

#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;
}

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

#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