演员表签名变窄

时间:2018-11-27 09:43:02

标签: c++ casting

If the destination type is signed, the value does not change if the source integer can be represented in the destination type.

如果我理解得很好,是否可以保证:

static_cast<std::int8_t>(static_cast<std::int16_t>(-3)) == -3

因为-3可以用std :: int8_t表示。

因此以二进制补码为例:

然后在two's complement function的示例中,我是否需要将中间对象强制转换为std :: uintmax_t?

#include <type_traits>

template <typename T>
T twos_complement(T val)
{
    typedef std::make_unsigned<T>::type U;

    return static_cast<T>(-static_cast<uintmax_t>(static_cast<U>(val)));
}

因为

return static_cast<T>(-static_cast<U>(val));

在一元减号之前应用积分提升是否可以“如果T比int窄,则将强制转换为无符号类型的效果”?

3 个答案:

答案 0 :(得分:4)

为什么不能像这样得到两者的补码?

uint32_t num = 10;
uint32_t cmp = ~num + 1; // this is two's complement of 10.

这不适合您吗?

编辑:如果您担心可能会发生溢出(无论是有符号签名还是无符号签名),请先执行以下操作:

if(~num == std::numeric_limits<MyIntType>::max()) {
    // overflow mitigation
}

您还可以使用std::is_signedstd::is_unsigned以适当的方式静态检查您的类型是带符号的还是无符号的,以缓解溢出问题。

答案 1 :(得分:2)

带符号/无符号表示形式取决于平台。即使大多数现代平台使用二进制补码表示有符号数,您也无法做出此假设。使用static_cast执行二进制补码不是正确的方法。如果您想自己进行位操作,请使用固定大小的无符号类型,如《量子物理学家》的回答(但要再次注意,如果加法发生溢出,将会发生什么取决于平台)。

答案 2 :(得分:1)

适应与C ++强制转换相关联的代码:

#include <cstdint>

template <typename T>
T twos_complement(T val)
{
    return static_cast<T>(-static_cast<uintmax_t>(val));
}