将 char 设置为所有真位
Setting char to all true bits
我正在尝试将 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;
这里出了什么问题?
数字11111111
是十进制常量,不是二进制。虽然可以使用八进制或十六进制常量,但没有二进制常量(至少不是标准的)。
如果您想要一个所有位都已设置的数字,只需将按位补码运算符 ~
应用于 0:
unsigned char foo = ~0u;
不要将十进制的 0
和 1
与二进制的 0
和 1
混淆。当您将 11111111
分配给 foo
时,它是十进制基本文字而不是二进制文字。事实上,按照 C 标准,没有什么比二进制文字更好的了。虽然,一些编译器支持它作为扩展。如果你想将 char
设置为所有真 (1
) 位,你可以这样做:
foo = ~(foo & 0);
unsigned char foo = ~0u;
, 回答得很好,适用于:
unsigned char
char
即 unsigned.
char
即 signed 并且具有 usual 实现定义的转换行为。
char foo = ~0u;
调用实现定义的行为 (C111 6.3.1.3 3),当 char
为 [=48 时,将超出范围的 unsigned
设置为 char
=]signed 并且可能不会产生全 1 位模式。
首先考虑:认识到在罕见的平台上,全一 char
是陷阱表达式。我们假设情况并非如此。
请注意,使用罕见的符号幅度编码,signed char
的全 1 位模式不会转换为 int
的全 1 位模式。这可能会影响编码目标。
如果代码想直接初始化一个 char
(signed 或 unsigned)而不用担心定义的转换实现行为,也不依赖编码作为 2 的补码、1 的补码或符号幅度,也不是范围,也不是 CHAR_BIT
值。
复合文字 C11
char mx1 = ( union { unsigned char uc; char c; } ) { .uc = -1u } .c;
联盟
const union {
unsigned char uc;
char c;
} ones = { -1u };
char mx2 = ones.c;
或
// (-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
// This may not work on rare sign-magnitude as it invokes implementation defined behavior
char mx4 = ~0;
Setting char to all true bits
#include <limits.h>
char all_ones = CHAR_MIN | CHAR_MAX;
在所有 char
位宽、char
符号和整数编码下都能正常工作1.
char
可能是signed或unsigned,如果signed,则可以编码为 2 的补码,或者很少编码为 1 的补码或符号大小。 Examples。它至少有 8 位,但在 select 平台上它更宽。没有填充位。
本质上,我们在寻找
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
的解决方案会调用实现定义的行为。所以结果可能不是所有想要的结果。
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised. C11dr §6.3.1.3 3
// 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`s complement 系统中,全 1 位模式可能是 -0 或陷阱。当陷阱时,无解。
我正在尝试将 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; 这里出了什么问题?
数字11111111
是十进制常量,不是二进制。虽然可以使用八进制或十六进制常量,但没有二进制常量(至少不是标准的)。
如果您想要一个所有位都已设置的数字,只需将按位补码运算符 ~
应用于 0:
unsigned char foo = ~0u;
不要将十进制的 0
和 1
与二进制的 0
和 1
混淆。当您将 11111111
分配给 foo
时,它是十进制基本文字而不是二进制文字。事实上,按照 C 标准,没有什么比二进制文字更好的了。虽然,一些编译器支持它作为扩展。如果你想将 char
设置为所有真 (1
) 位,你可以这样做:
foo = ~(foo & 0);
unsigned char foo = ~0u;
,
unsigned char
char
即 unsigned.char
即 signed 并且具有 usual 实现定义的转换行为。
char foo = ~0u;
调用实现定义的行为 (C111 6.3.1.3 3),当 char
为 [=48 时,将超出范围的 unsigned
设置为 char
=]signed 并且可能不会产生全 1 位模式。
首先考虑:认识到在罕见的平台上,全一 char
是陷阱表达式。我们假设情况并非如此。
请注意,使用罕见的符号幅度编码,signed char
的全 1 位模式不会转换为 int
的全 1 位模式。这可能会影响编码目标。
如果代码想直接初始化一个 char
(signed 或 unsigned)而不用担心定义的转换实现行为,也不依赖编码作为 2 的补码、1 的补码或符号幅度,也不是范围,也不是 CHAR_BIT
值。
复合文字 C11
char mx1 = ( union { unsigned char uc; char c; } ) { .uc = -1u } .c;
联盟
const union {
unsigned char uc;
char c;
} ones = { -1u };
char mx2 = ones.c;
或
// (-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
// This may not work on rare sign-magnitude as it invokes implementation defined behavior
char mx4 = ~0;
Setting char to all true bits
#include <limits.h>
char all_ones = CHAR_MIN | CHAR_MAX;
在所有 char
位宽、char
符号和整数编码下都能正常工作1.
char
可能是signed或unsigned,如果signed,则可以编码为 2 的补码,或者很少编码为 1 的补码或符号大小。 Examples。它至少有 8 位,但在 select 平台上它更宽。没有填充位。
本质上,我们在寻找
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
的解决方案会调用实现定义的行为。所以结果可能不是所有想要的结果。
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised. C11dr §6.3.1.3 3
// 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`s complement 系统中,全 1 位模式可能是 -0 或陷阱。当陷阱时,无解。