c++ - 运行时错误: Integer Overflow for Complement Number Problem

标签 c++ numbers bit-manipulation

我有 3 种方法来对给定的二进制数求补。第一种和第三种方法不会出现任何整数溢出错误。您能解释一下为什么第二种方法会出现此运行时错误吗? 代码如下:

 int findComplement1(int num) {
        if(num==0)
            return 1;

        int n=num;
        int bit=1;
        while(n>0)
        {
         num=num^bit;
         n/=2;
         bit=bit<<1;
        }
        return num;
    }

//Got Integer Overflow
int findComplement2(int num)
{
    int n = floor(log2(num)+1);;
    int num_with_all_ones =(int) (1<<n)-1;
    return (num_with_all_ones^num);
}

int findComplement3(int num)
{
    if(num==0)
        return 1;
    int result=0;
    int power=1;
    while(num>0)
    {
        int pop=num%2;
        int c=(num%2)^1;
        result+=c*power;
        power=power<<1;
        num=num>>1;
    }
    return result;
}

这是错误消息: 运行时错误消息:第 7 行:Char 44:运行时错误:有符号整数溢出:-2147483648 - 1 无法以“int”类型表示(solution.cpp) 摘要:UndefinedBehaviorSanitizer:未定义行为 prog_joined.cpp:16:44

最后执行的输入:2147483647

最佳答案

TLDR:这是一个下溢的二进制补码算术问题。

您的错误正确地表明“-2147483648 - 1 无法以“int”类型表示”。有关整数类型的一些背景知识可能会有所帮助。

整数类型是数学整数的四字节(32 位)表示形式。因此它应该能够表示 2^32 -1 个正整数。然而,很快我们就发现负整数也需要被表示。解决方案是使用最高有效位(MSB:大端排序中最左边的位)作为标志来确定整数是否被解释为正数或负数。将 MSB 设置为 1 会提醒计算机后面的 31 位表示负整数,设置为 0 表示正整数。基本上,这称为二进制补码,尽管快速在线搜索会更清楚、更详细地解释它。因此,整数类型的范围为 [-2,147,483,648 到 2,147,483,647],其中 -2,147,483,648 以二进制表示为 0b10000000000000000000000000000000,2,147,483,647 以二进制表示为 0b011111111 11111111111111111111111。正如 2,147,483,647 加 1 会溢出到最大负整数的二进制表示形式一样,从 -2,147,483,648 中减 1 也会下溢到最大正整数。

关于第二个函数中的运行时错误。

int findComplement2(int num){

    int n = floor(log2(num)+1);;            
    int num_with_all_ones =(int) (1<<n)-1;
    return (num_with_all_ones^num);
}
findComplement2(2147483647);

当参数num为2,147,483,647时,变量n被赋值为31(floor(30.9999999993 + 1),去掉多余的分号就好了,因此num_with_all_ones被赋值为1后面表示的二进制数的差值31 个 0(或者如我们在上面看到的,最大负整数 -2147483648)和 1。这会导致下溢错误,从而导致计算机引发运行时错误。

注意这是我第一次在 Stack 上回答,所以如果有人对下次如何更好地回答有建议,我将不胜感激。

关于c++ - 运行时错误: Integer Overflow for Complement Number Problem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61627167/

相关文章:

c# - C# 中的位运算

python - 1's and 0' s python 位的序列

c - 通过按位运算获取两个数中的较大者

c++ - C++中如何将整数转换为字符串

c++ - 是否可以通过 TCP/IP 套接字绑定(bind)并监听一个 IP 地址? (Linux/C)

javascript - 从字符串 JavaScript 中提取数字

java堆栈跟踪的行号与hadoop lib不匹配

c++ - 如何从 C++ 文件中读取由逗号分隔的全名?

c++ - 从哈希表 C++ 中删除

numbers - 数字格式 : Get rid of thousand separators (comma, 引用等)