Home > Net >  How to cast an integer value to a type with double width?
How to cast an integer value to a type with double width?

Time:12-13

Sometimes I need to perform intermediate calculations with double-size values, for example - in this function, which returns a product of two numbers by modulo m:

template <typename T, typename DT>
T multiply(T x, T y, T mod)
{
  return (static_cast<DT>(x % mod) * (y % mod)) % mod;
}

This casting will be necessary if the mod value is close enough to the maximal value of the type T. As a result I have to call this function with two template parameters:

z = multiply<int32_t, int64_t>(x, y, m)

This looks ugly, and is error-prone. Is it any way to automatically declare the double-sized type DT (corresponding to the type T) inside such a function?

Also I see this document, which is supposed to solve this problem, but I couldn't find any info about its implementation in any popular C compiler.

CodePudding user response:

I might be missing why you want exactly double-sized type, but provided you consider only signed and unsigned integrals, you can just pick the max-size compatible type for the calculations:

template<typename T>
T multiply(T x, T y, T mod) {
    static_assert(std::is_integral_v<T>, "Only integral types are expected");

    using CT = std::conditional_t<std::is_signed_v<T>, long long,
        std::conditional_t<std::is_unsigned_v<T>, unsigned long long, T>>;
    return (static_cast<CT>(x % mod) * (y % mod)) % mod;
}
  • Related