如果我理解得很好,是否可以保证:
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窄,则将强制转换为无符号类型的效果”?
答案 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_signed
和std::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));
}