我们可以在while循环内左移一个值吗?

问题描述 投票:0回答:2

我尝试使用左移来使用计数器来识别setbit。当我尝试左移var时,我发现它陷入了无限循环,只有零被打印。以下代码有什么问题?在while循环内使用左移甚至合法吗?

#include <stdio.h>
#include <limits.h>
int main(int argc, char **argv)
{
    int var =1;

    while(var<INT_MAX)
    {   
        var = var<<1;
        printf("%d\n", var);        
    }

    return 0;
}
c while-loop operators bit-shift unsigned-integer
2个回答
2
投票

在循环内使用移位操作非常好。您的代码存在的问题是var永远不会等于或大于INT_MAX

为了更好的理解,让我用8位有符号整数而不是32位有符号整数解释问题。

您以值var = 00000001b开头(b表示它是一个二进制数),而8位带符号整数的INT_MAXINT_MAX = 01111111b = 127(请注意,最高位为0,这是因为它是符号位)

现在,如果您向左移动var,则将此单1缓慢向右移动

var << 1 = 00000010b =    2
var << 2 = 00000100b =    4
var << 3 = 00001000b =    8
var << 4 = 00010000b =   16
var << 5 = 00100000b =   32
var << 6 = 01000000b =   64
var << 7 = 10000000b = -128
var << 8 = 00000000b =    0

在第七次移位后,1位达到最高位,但是由于我们有一个8位带符号整数,因此我们将10000000b解释为不是128,而是解释为-128,因此var < INT_MAX将始终为真。

如果您不知道为什么会这样,您可能需要阅读two complement号。


1
投票

在此循环中

while(var<INT_MAX)
{   
    var = var<<1;
    printf("%d\n", var);        
}

var永远不能等于INT_MAX,因为其中只设置了一位

int var = 1;

已转移。

尝试以下循环:

while(var<INT_MAX)
{   
    var = ( var << 1 ) + 1;
    printf("%d\n", var);        
} 

这里是一个演示程序,为简单起见,这里使用了签名类型signed char,而不是使用signed type int。

#include <stdio.h>
#include <limits.h>

int main(void) 
{
    signed char var = 1;

    while ( var  < SCHAR_MAX )
    {   
        var = ( var << 1 )  + 1;
        printf( "%d\n",  var );        
    }

    return 0;
}

程序输出为

3
7
15
31
63
127

并且根据C标准(5.2.4.2.1整数类型<limits.h>的大小]

— maximum value for an object of type signed char
SCHAR_MAX +127 // 2^7 − 1
© www.soinside.com 2019 - 2024. All rights reserved.