简体   繁体   English

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

[英]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. iintunsigned的提升是确定性的,并且在对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. 如果已签名,则cc >> 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.

相关问题 ANSI C是否支持带符号/无符号位字段? - Does ANSI C support signed / unsigned bit fields? 正确解释有符号与无符号 - Correct interpretation signed vs unsigned 有符号和无符号int之间的强制转换是否在内存中保持变量的精确位模式? - Does cast between signed and unsigned int maintain exact bit pattern of variable in memory? 有符号和无符号,以及C中的位扩展如何工作 - Signed and unsigned, and how bit extension works in C 为什么 C++ 标准指定在具有混合符号的二元运算中将有符号整数强制转换为无符号? - Why does C++ standard specify signed integer be cast to unsigned in binary operations with mixed signedness? 在编译为unsigned时,C编译器是否可以更改位表示? - Can a C compiler change bit representation when casting signed to unsigned? 按位C-从无符号int解压缩有符号的10位数字 - Bitwise C - Unpacking signed 10 bit numbers from an unsigned int C:如何将2 32位无符号整数的结果保存为有符号整数 - C: How to save the result of 2 32 bit unsigned integer into a signed integer 如何在 C 中使用有符号或无符号整数进行位映射? - How to use signed or unsigned integer for bit mapping in C? C Standard是否保证#error指令的诊断消息? - Does C Standard guarantee diagnostic message for #error directive?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM