Runtime Error : Integer Overflow for Complement Number Problem

Runtime Error : Integer Overflow for Complement Number Problem

我有 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 行:字符 44:运行 时间错误:有符号整数溢出:-2147483648 - 1 无法在类型 'int' (solution.cpp) 中表示 摘要:UndefinedBehaviorSanitizer:未定义行为 prog_joined.cpp:16:44

最后执行的输入:2147483647

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

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

整数类型是 four-byte(32 位)数学整数表示。因此它应该能够表示 2^32 -1 个正整数。但是,很快就很明显负整数也需要表示。解决方案是使用最高有效位(MSB:大端排序中最左边的位)作为标志来确定整数将被解释为正数还是负数。将 MSB 设置为 1 会提醒计算机后面的 31 位代表一个负整数,设置为 0 则代表一个正整数。基本上,这称为二进制补码,尽管快速在线搜索会更清楚、更详细地解释它。 As a result the range of the integer type is [-2,147,483,648 to 2,147,483,647] where -2,147,483,648 is represented in binary as 0b10000000000000000000000000000000 and 2,147,483,647 as 0b01111111111111111111111111111111.正如 2,147,483,647 加一会溢出到最大负整数的二进制表示一样,-2,147,483,648 减一也会下溢到最大正整数。

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

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 表示的数字。这会导致下溢错误,从而导致您的计算机引发运行时错误。

N.B。这是我有史以来第一个 Stack 答案,所以如果有人对下次如何更好地回答有任何建议,将不胜感激。