Unsigned/Signed 带转换的整数加法
Unsigned/Signed Integer Addition with Casting
在 C++ 中,是否可以保证如果我使用固定宽度整数的有符号和无符号版本来执行运算,我会得到相同的结果?
也就是说,如果我这样做:
uint64_t a = [any number];
uint64_t b = [any number];
uint64_t resultOne = a + b;
uint64_t resultTwo = (uint64_t)(((int64_t) a) + ((int64_t) b));
无论我为 a 和 b 使用什么值,是否保证 resultOne 和 resultTwo 总是产生相同的输出?
对于无符号类型,加法保证环绕:如果将 1
添加到最大值 uint64_t
,您将得到 0
.
对于带符号的类型,在 C 和 C++ 中,环绕是未定义的行为:任何事情都可能发生,实际上,如果您启用了优化,编译器可以做一些您意想不到的事情。
所以不,标准不保证这一点。
但是,许多编译器提供了一个选项,作为标准的扩展,保证签名类型的包装行为,在这种情况下,答案是肯定的。例如,参见 GCC 和 Clang 的-fwrapv
。
在 C++ 中,是否可以保证如果我使用固定宽度整数的有符号和无符号版本来执行运算,我会得到相同的结果? 也就是说,如果我这样做:
uint64_t a = [any number];
uint64_t b = [any number];
uint64_t resultOne = a + b;
uint64_t resultTwo = (uint64_t)(((int64_t) a) + ((int64_t) b));
无论我为 a 和 b 使用什么值,是否保证 resultOne 和 resultTwo 总是产生相同的输出?
对于无符号类型,加法保证环绕:如果将 1
添加到最大值 uint64_t
,您将得到 0
.
对于带符号的类型,在 C 和 C++ 中,环绕是未定义的行为:任何事情都可能发生,实际上,如果您启用了优化,编译器可以做一些您意想不到的事情。
所以不,标准不保证这一点。
但是,许多编译器提供了一个选项,作为标准的扩展,保证签名类型的包装行为,在这种情况下,答案是肯定的。例如,参见 GCC 和 Clang 的-fwrapv
。