[英]Does c standard guarantee bit pattern interpretation for signed and unsigned?
Does the C standard state how bit representations should be interpreted? C标准是否规定应如何解释位表示? In other words do the following if conditions always evaluate to true?
换句话说,如果条件始终为真,则执行以下操作吗? Assume sizeof (int) = 4 and CHAR_BIT = 8
假设sizeof(int)= 4且CHAR_BIT = 8
unsigned u = 0xffffffff;
if (u == 4294967295) /* do something */
int i = 0xffffffff;
if (i == -1) /* do something */
unsigned u = (int)0xffffffff;
if (u == 0xffffffff) /* do something */
int i = hex_literal;
unsigned u;
memcpy (&u, &i, sizeof (u));
if (i == u) /* do something */
if ((i & 0x7fffffff) == (u & 0x7fffffff)) /* do something */
int i = hex_literal;
unsigned u = i;
if (i == u) /* do something */
unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */
int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */
char c = 0xff;
if (c >> 4 == 0xf) /* do something */
signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */
For unsigned, yes. 对于未签名,是的。 For signed types, no;
对于带符号的类型,否; the standard permits 2's complement, 1's complement or sign-magnitude representations.
该标准允许2的补码,1的补码或符号幅度表示。 The relevant section of the standard (C99) is 6.2.6.2.
标准(C99)的相关部分是6.2.6.2。
A separate issue is that code such as unsigned u = (int)0xffffffff
invokes undefined behaviour, as this causes an integer overflow (section 6.3.1.3). 一个单独的问题是,诸如
unsigned u = (int)0xffffffff
调用未定义的行为,因为这会导致整数溢出(第6.3.1.3节)。
Yet another issue is that code such as char c = 0xff; c >> 4
另一个问题是该代码,例如
char c = 0xff; c >> 4
char c = 0xff; c >> 4
is implementation-defined for two reasons. char c = 0xff; c >> 4
是实现定义的,这有两个原因。 Firstly, char
can either be signed
or unsigned
. 首先,
char
可以是有signed
也可以是unsigned
。 Secondly, if it's signed
, then right-shifting a negative number is implementation-defined (section 6.5.7). 其次,如果它是带
signed
,则右移负数是实现定义的(第6.5.7节)。
I will make the added assumption that no types have padding bits on the implementation under discussion. 我将做出额外的假设,即所讨论的实现中没有类型具有填充位。 Let's take them one at a time:
让我们一次带他们一个:
unsigned u = 0xffffffff;
if (u == 4294967295) /* do something */
Yes. 是。
int i = 0xffffffff;
if (i == -1) /* do something */
No. Conversion of an out-of-range number to a signed type gives an implementation-defined result. 否。将超出范围的数字转换为带符号的类型将给出实现定义的结果。
unsigned u = (int)0xffffffff;
if (u == 0xffffffff) /* do something */
No, same reason as the previous example. 不,与前面的示例相同。
int i = hex_literal;
unsigned u;
memcpy (&u, &i, sizeof (u));
if (i == u) /* do something */
if ((i & 0x7fffffff) == (u & 0x7fffffff)) /* do something */
Yes. 是。 The standard guarantees that each value bit in a signed type has the same value in the object representation of the corresponding unsigned type.
该标准保证有符号类型中的每个值位在对应的无符号类型的对象表示中具有相同的值。
int i = hex_literal;
unsigned u = i;
if (i == u) /* do something */
Yes. 是。 The promotion of
i
from int
to unsigned
is deterministic and produces the same value both in the assignment to u
and in the comparison. i
从int
到unsigned
的提升是确定性的,并且在对u
的赋值和比较中都产生相同的值。
unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */
Yes, but only if hex_literal
is in the range of (positive) values representable by an int
- otherwise the implementation-defined result strikes again. 是的,但是仅当
hex_literal
处于可以由int
表示的(正)值范围内时,否则实现定义的结果将再次出现。
int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */
u == hex_literal
will always evalulate to true, but i == hex_literal
need only do so if hex_literal
is in the range of values representable by an int
. u == hex_literal
将始终评估为true,但是i == hex_literal
仅在hex_literal
处于int
表示的值范围内i == hex_literal
需要这样做。
char c = 0xff;
if (c >> 4 == 0xf) /* do something */
char
may be signed or unsigned. char
可以是已签名或未签名。 If it is unsigned then the test will be true; 如果未签名,则测试为true;否则为true。 if signed, then
c
and c >> 4
will have implementation-defined values, so it may not be true. 如果已签名,则
c
和c >> 4
将具有实现定义的值,因此可能不正确。
signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */
c
will have an implementation-defined value, so the test may not be true. c
将具有实现定义的值,因此测试可能不正确。
Note that all of your questions other than the memcpy()
one pertain only to the values rather than the representation . 请注意,除了
memcpy()
以外,您所有的问题仅与值有关,而与表示有关 。
Unsigned numbers have guaranteed modulo 2^n arithmetic. 无符号数保证了模2 ^ n的模运算。 There is no such guarantee for signed ones.
签名者没有这样的保证。
Nothing is said about bit patterns. 关于位模式,什么也没说。 Note that 0xfffffff is not a "bit pattern", it is a number (whose "bit patterns" have no meaning for the C++ standard) which is guaranteed to satisfy x + 1 = 0 if
x
is an 32 bit unsigned number to which you assigned 0xffffffff. 请注意,0xfffffff不是“位模式”,它是一个数字(其“位模式”对于C ++标准没有意义),如果
x
是您要使用的32位无符号数,则保证满足x + 1 = 0分配为0xffffffff。
Key item to memorize is that hex literals (eg 0x0F
) refer to the value (here: 15
), not the order in which bits and bytes are stored physically. 要记住的关键项是十六进制文字(例如
0x0F
)是指值 (此处为15
),而不是物理上存储位和字节的顺序。
It is machine dependant how this is stored - some will store the least significant bit first, others the high bit first, and AFAIK on x86 it's least significant byte first but high bit first. 它是依赖于机器这是怎么保存-有些人会首先存储最低显著位,其他高位第一次,据我所知在x86它至少显著字节第一,但高位第一。
But it is always true, that 0x000F
equals 15
. 但始终是真的,
0x000F
等于15
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.