3

C99 (ISO/IEC 9899:1999)

6.2.6.2/1 整数类型

任何填充位的值都是未指定的。45)符号位为零的有符号整数类型的有效(非陷阱)对象表示是相应无符号类型的有效对象表示,并且应表示相同的值。

对于任何整数类型,所有位都为零的对象表示应是该类型中值零的表示。

在 C99 标准中,保证所有位都为零的整数类型表示0相应类型中的值。然而,这能保证底层的二进制值是我们所期望的吗?

例如:

unsigned x = 42;

我们通常希望机器将此十进制42值作为二进制值存储在内存中101010

但是,某些古怪的机器架构是否可以存储与42二进制值相同的十进制011011值(不一定是出于实际原因,而仅仅是因为它可以)?

如果是这样,请考虑使用右移操作的以下代码:

unsigned y = x>>1;    /* 101010>>1 or 011011>>1 */

y保存十进制值2110101二进制)还是十进制值1301101二进制)?

2C99 标准是否对按位运算后无符号整数类型的十进制表示做出任何保证——例如,在所有机器体系结构上,右移是否保证等于整数除法?

4

3 回答 3

3

标准中未指定整数的表示形式。
但是,>>and的行为<<是根据位的含义定义的,而不是它们的位置。
因此>> 1,将表示 4 的位移动到表示 2 的位,而不管这些位实际在哪里。

引用C99 标准第 6.5.7 节:

E1 >> E2的结果是E1右移E2位位置。如果E1具有无符号类型或E1具有有符号类型和非负值,则结果的值是E1 / 2 E2的商的整数部分。如果E1具有带符号类型和负值,则结果值是实现定义的。

于 2013-06-11T13:49:05.687 回答
1

操作员将>>移动位。在正常系统下,这意味着只是转移它们。但实际上,我们将表示 position 的位2^3移动到 position 2^2,无论它在哪里。

所以在所有系统上,assert(42 >> 1 == 21).


至于你的第二个问题,的,只要你忽略陷阱/填充位。这些显然是不同的,但通常对您来说也是不可见的。

于 2013-06-11T13:39:09.630 回答
1

该标准不保证事物如何物理存储在内存中。没有必要这样做。该机器可以是三进制、十进制或物理级别的模拟,而不是二进制。机器甚至不需要具有物理位。

它对 unsigned int 的所有保证是按位运算符影响“位”作为数字的二进制位置表示的元素。这些实际上是虚拟位。它们可以直接对应于物理位(在实践中通常是这种情况),或者它们可以是纯概念的。

运算符保证将>>这些虚拟位向右移动,这意味着它始终保证将正整数值除以 2。因此,对于x = 42this的初始值x = x >> 1保证产生21in x。这意味着如果某台机器在物理上表示42011011,则该机器的编译器将需要生成代码,将该表示更改4221(无论它是什么)的表示,即使后者在物理上看起来不像“右移”011011图案。

于 2013-06-11T14:40:29.210 回答