c 标准是否保证有符号和无符号的位模式解释?

发布于 2024-12-12 03:18:48 字数 868 浏览 3 评论 0原文

C 标准是否规定了应如何解释位表示?换句话说,以下 if 条件总是评估为 true 吗?假设 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 */

Does the C standard state how bit representations should be interpreted? In other words do the following if conditions always evaluate to true? Assume sizeof (int) = 4 and 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 */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

∞琼窗梦回ˉ 2024-12-19 03:18:48

我将做出额外的假设,即所讨论的实现中没有任何类型具有填充位。让我们一次一个地讲:

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 */

是的。 iintunsigned 的提升是确定性的,并且在对 uu 的赋值中产生相同的值在比较中。

unsigned u = hex_literal;
int i = u;
if (i == u) /* do something */

是的,但前提是 hex_literal 位于由 int 表示的(正)值范围内 - 否则实现定义的结果会再次出现。

int i = hex_literal;
unsigned u = hex_literal;
if (i == hex_literal && u == hex_literal) /* do something */

u == hex_literal 将始终评估为 true,但 i == hex_literal 仅当 hex_literal 位于可表示的值范围内时才需要这样做一个int

char c = 0xff;
if (c >> 4 == 0xf) /* do something */

char 可以是有符号的,也可以是无符号的。如果未签名,则测试为真;如果已签名,则 cc >>> 4 将具有实现定义的值,因此它可能不正确。

signed char c = 0xff;
if (((c >> 4) & 0xff) == 0xf) /* do something */

c 将具有实现定义的值,因此测试可能不正确。

请注意,除了 memcpy() 问题之外,您的所有问题仅与有关,而不与表示有关。

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.

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.

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.

char c = 0xff;
if (c >> 4 == 0xf) /* do something */

char may be signed or unsigned. If it is unsigned then the test will be true; if signed, then c and c >> 4 will have implementation-defined values, so it may not be true.

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.

Note that all of your questions other than the memcpy() one pertain only to the values rather than the representation.

风吹过旳痕迹 2024-12-19 03:18:48

对于未签名的,是的。对于有符号类型,没有;该标准允许 2 的补码、1 的补码或符号数值表示。标准(C99)的相关章节是6.2.6.2。

另一个问题是诸如 unsigned u = (int)0xffffffff 之类的代码会调用未定义的行为,因为这会导致整数溢出(第 6.3.1.3 节)。

另一个问题是诸如 char c = 0xff; 之类的代码。 c>> 4 是实现定义的有两个原因。首先,char 可以是有符号无符号。其次,如果它是有符号的,则右移负数是实现定义的(第 6.5.7 节)。

For unsigned, yes. For signed types, no; the standard permits 2's complement, 1's complement or sign-magnitude representations. The relevant section of the standard (C99) is 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).

Yet another issue is that code such as char c = 0xff; c >> 4 is implementation-defined for two reasons. Firstly, char can either be signed or unsigned. Secondly, if it's signed, then right-shifting a negative number is implementation-defined (section 6.5.7).

寂寞笑我太脆弱 2024-12-19 03:18:48

无符号数保证模 2^n 算术。对于签名的则没有这样的保证。

没有提及位模式。请注意,0xfffffff 不是“位模式”,它是一个数字(其“位模式”对于 C++ 标准没有意义),如果 x 是一个,则保证满足 x + 1 = 0您分配给 0xffffffff 的 32 位无符号数。

Unsigned numbers have guaranteed modulo 2^n arithmetic. 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.

后来的我们 2024-12-19 03:18:48

需要记住的关键一点是,十六进制文字(例如0x0F)指的是(此处:15),而不是位和的顺序。字节是物理存储的。

它的存储方式取决于机器 - 有些会首先存储最低有效位,另一些则首先存储高位,据我所知,在 x86 上,它首先存储最低有效字节,但首先存储高位第一的。

0x000F 等于15 始终是正确的。

Key item to memorize is that hex literals (e.g. 0x0F) refer to the value (here: 15), not the order in which bits and bytes are stored physically.

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.

But it is always true, that 0x000F equals 15.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文