C99标准是否保证了unsigned int的二进制表示?

时间:2013-06-11 13:24:12

标签: c portability c99 standards-compliance

C99(ISO / IEC 9899:1999)

  

6.2.6.2/1整数类型

     

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

     

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

在C99标准中,保证所有位为零的整数类型表示相应类型中的值0。但是,这是否能保证基础二进制值是我们期望的那样?

例如:

unsigned x = 42;

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

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

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

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

y会保持小数值21(二进制为10101),还是十进制值13(二进制为01101)?

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

3 个答案:

答案 0 :(得分:3)

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

引用C99 standard部分6.5.7:

  

E1&gt;&gt;的结果E2 E1 右移 E2 位位置。如果 E1 具有无符号类型   或者如果 E1 具有有符号类型和非负值,则结果的值是 E1 / 2 E2 商的不可分割部分。如果 E1 具有签名类型和负值,则生成的值是实现定义的。

答案 1 :(得分:1)

>>运算符会移动位。在正常系统下,这意味着只是转移它们。但实际上,我们会将代表位置2^3的位移动到位置2^2,无论它位于何处。

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


关于你的第二个问题,,只要你忽略陷阱/填充位。那些可能显然是不同的,但通常也是你看不见的。

答案 2 :(得分:1)

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

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

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