带有 unsigned int 参数的 C++ 函数在用负数调用它时得到奇怪的结果

标签 c++

我是 C++ 的新手,我对以下代码的 C++ 行为感到困惑:

#include <iostream>
void hello(unsigned int x, unsigned int y){
    std::cout<<x<<std::endl;
    std::cout<<y<<std::endl;
    std::cout<<x+y<<std::endl;
}

int main(){
    int a = -1;
    int b = 3;
    hello(a,b);
    return 1;
}

输出中的 x 是一个非常大的整数:4294967295,我知道负整数转换为无符号会像这样。但是为什么输出中的x+y是2呢?

最佳答案

与其他答案相反,这里没有未定义的行为,也没有溢出。无符号整数使用模 2n 算法。

标准第 4.7 节第 2 段说“如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模 2n其中 n 是用于表示无符号类型的位数)。这表明 -1 等于最大可能的无符号整数(模 2n)。

第 3.9.1 节第 4 段说“无符号整数,声明为无符号,应遵守算术模 2n 的法则,其中 n 是该特定大小的整数的值表示中的位数。”为了清楚地说明这意味着什么,该子句的脚注说“这意味着无符号算术不会溢出,因为无法由结果无符号整数类型表示的结果以比最大值大 1 的数字为模减少可以用生成的无符号整数类型表示。”


换句话说,将 -1 转换为 4294967295 不仅仅是定义的行为,它是必需的行为(假设为 32 位整数)。同样,将 3 添加到该值并产生 2 作为结果也是必需的行为。在这种情况下,n 的值无关紧要。 hello()打印的第三个值必须为2否则不符合标准。

关于带有 unsigned int 参数的 C++ 函数在用负数调用它时得到奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21896036/

相关文章:

c++ - KD树,慢树构建

c++ - 手动添加 vector 异常处理程序

c++ - 使用尾随垃圾 boost gzip 读取文件

c++ - 奇怪的 GCC 错误 : expected primary-expression before ',' token

c++ - 使用 MsgPack 通过 ZeroMQ (zmqpp) 发送数据给出 'msgpack::v1::insufficient_bytes' 错误

c++ - 检查彩虹数组(检查数组的反向样式是否与自身匹配)

java - 数组的排列

c++ - 如何在 istream& 运算符中输入字符串

c++ - 库、DLL 和 .h 文件

c++ - 如何编写查找表来映射像素强度 (OpenCV)