为什么我不能使用int的第一位?

时间:2016-05-24 14:59:08

标签: c bit-manipulation shift

我正在尝试使用int的所有位生成一个随机数。当我使用rand()函数时,它似乎永远不会使用第一位,所以我试图把整个东西移到一个地方。但是,当我尝试打印新移位的数字时,它总是打印4294967295,所以我猜这是一个溢出。但是为什么我不能使用那个位呢?有办法吗?

如果没有使用第一位,它就可以正常工作(打印是在随机数移位之前和之后):

00000100001100111111001010010111
00001000011001111110010100101110

但如果需要第一位,则会发生这种情况:

01010110100001110011110011011111
42949672950101101000011100111100110111110

请帮忙!!它在技术上有效,它只是先输出数字......

 typedef struct{
    int blocks[NUM_BLOCKS];
} WWord;

void printbits(unsigned int n){
    int i;
    //printf("%u = ",n);
    for(i=SIZE_OF_INT*SIZE_OF_BYTE-1;i>=0;i--){
        int mask = 1<<i;
        int maskedn = n&mask;
        int thebit = maskedn >> i;
        printf("%u",thebit);
    }
    printf("\n");
}

void fillword(WWord *word){
    int i;
    for(i=0; i<NUM_BLOCKS;i++){
        unsigned int ran = rand();
        printbits(ran);
        ran = ran<<1;
        printbits(ran);
        word->blocks[i] = ran;
        //word->blocks[i]<<1;
        printf("\n");
    }
}

2 个答案:

答案 0 :(得分:5)

您似乎在printbits函数中使用 int 而不是 unsigned int 。所以它将它转换为 signed int ,它使用MSB作为符号位。将那些 int 更改为 unsigned int 它将起作用。

更改您的功能如下:

void printbits(unsigned int n){
    int i;
    //printf("%u = ",n);
    for(i=SIZE_OF_INT*SIZE_OF_BYTE-1;i>=0;i--){
        unsigned int mask = 1u<<i;
        unsigned int maskedn = n&mask;
        unsigned int thebit = maskedn >> i;
        printf("%u",thebit);
    }
    printf("\n");
}

答案 1 :(得分:2)

您的=IFERROR(INDEX($B:$B,IF(COLUMN(A:A)>COUNTIF($A:$A,$D1),1500000,MATCH($D1,$A:$A,0)+COLUMN(A:A)-1)),"") 被声明为maskedn类型。这是签名数据类型。

但您的int类型为ran

对于位移,C和C ++对有符号和无符号整数类型的处理方式不同:unsigned运算符对有符号整数的行为是根据C标准实现定义的,如@chux指出的那样。评价。

但是,在大多数x86编译器上,签名的右移实现为arithmetic shift,这基本上意味着符号位(无符号表示中最重要的位)保留而不是向右移动。

如果设置有符号整数的MSB,则设置符号位,当您向右移动时,您将反复复制该符号位。请参阅this illustration from Wikipedia

这就是为什么你得到一个非常大的数字,4294967295,>>,或32位所有设置为1。

如果你小心在任何地方使用无符号整数,那么你将得到预期的行为,其中向右移动移动MSB,而不是复制它。