将char设置为所有真实位

时间:2018-02-08 21:08:23

标签: c bit-manipulation bitwise-or

我正在尝试将char中的所有位设置为true。

char foo = 00000000;
foo |= 11111111;
for (int i = 0; i < 8; i++) { //prints out bitwise
    printf("%d", !!((foo << i) & 0x80));
}

当foo全为0时,我得到11000111。 当foo == 00000110时,它打印11001111; 这里出了什么问题?

4 个答案:

答案 0 :(得分:8)

数字11111111是十进制常量,而不是二进制。虽然您可以使用八进制或十六进制常量,但没有二进制常量(至少不是标准常量)。

如果你想要一个设置了所有位的数字,只需将按位补码运算符~应用于0:

unsigned char foo = ~0u;

答案 1 :(得分:1)

unsigned char foo = ~0u;@dbush得到了很好的回答,效果很好:

  1. unsigned char
  2. char 未签名
  3. char 已签名并且通常实施定义了转化行为。
  4. char foo = ~0u;调用实施定义的行为(C111 6.3.1.3 3),当unsigned 签署<时,设置超出范围的charchar < / em>并且可能不会产生全1位模式。

    首先考虑:认识到在罕见的平台上,全1 char是一个陷阱表达式。我们假设这不是这种情况。

    请注意,对于罕见的符号幅度编码,signed char的全1位模式不会将{1}}转换为全1位模式。这可能会影响编码目标。

    如果代码想直接初始化int签名无符号)并且不担心转换实现定义的行为,也不依赖于编码为2的补码,1的补码或符号幅度,范围也不是char值。

    复合文字 C11

    CHAR_BIT

    <强>联合

    char mx1 = ( union { unsigned char uc; char c; } ) { .uc = -1u } .c;
    

    const union {
      unsigned char uc;
      char c;
    } ones = { -1u };
    char mx2 = ones.c;
    

    确定非2的补码上的值有点棘手,但通过分析可行。

    <强>〜0

    // (-1 | -2) is a one's complement all one bits      
    // -1 is the two's complement all one bits  
    // CHAR_MIN is the sign-magnitude all one bits  
    char mx3 = (-1 | -2) | -1 | CHAR_MIN;
    

答案 2 :(得分:0)

请勿将小数01与二进制01混淆。将11111111指定给foo时,它是十进制基础文字,而不是二进制文字。实际上,根据C标准,没有像二进制文字那样的东西。虽然,有些编译器支持它作为扩展。如果要将char设置为所有真(1)位,可以这样做:

foo = ~(foo & 0);

答案 3 :(得分:0)

  

将char设置为所有真位

#include <limits.h>
char all_ones = CHAR_MIN | CHAR_MAX;

在所有char位宽,char符号和整数编码 1 下正常工作。

char可以签名签名,如果签名,它可以编码为2的补码,或者很少编码补码或登录幅度。 Examples。它至少有8位,但在选择的平台上它更宽。没有填充位。

从本质上讲,我们正在寻找

char ones = CHAR_MAX;  // `char` is unsigned
char ones = -1;        // `char` is signed and 2's complement
char ones = ~0;        // `char` is signed and 1's complement (rare)
char ones = CHAR_MIN;  // `char` is signed and sign-magnitutde (rare)

签名char分配超出范围值的解决方案会调用实施定义的行为。所以结果可能不是所谓的所有结果。

  

否则,新类型已签名且值无法在其中表示;结果是实现定义的,或者引发实现定义的信号。 C11dr§6.3.1.33

// Almost always correct alternatives
char all_ones = ~0; // Work great but maybe not on rare sign-magnitude per 6.3.1.3 3
char all_ones = ~0u; // Always invokes 6.3.1.3 3 when char is signed.

1 在罕见的 one的补充系统中,全1位模式可能是-0或陷阱。当一个陷阱,没有解决方案是可以接受的。