首页 文章

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

提问于
浏览
3

C99(ISO / IEC 9899:1999)

6.2.6.2/1整数类型任何填充位的值都是未指定的.45)符号位为零的有符号整数类型的有效(非陷阱)对象表示是相应无符号类型的有效对象表示,并代表相同的 Value . 对于任何整数类型,所有位为零的对象表示应该是该类型中零值的表示 .

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

例如:

unsigned x = 42;

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

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

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

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

y 会保持十进制值 2110101 二进制),还是十进制值 1301101 二进制)?

在按位操作之后,C99标准是否对无符号整数类型的十进制表示做出任何保证 - 例如在所有机器架构中,保证等效于 2 的整数除法是正确的吗?

3 回答

  • 3

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

    引用C99 standard部分6.5.7:

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

  • 1

    >> 运算符将移动位 . 在正常系统下,这意味着只是转移它们 . 但实际上,无论它在哪里,我们都会采用代表位置_2585909的位,并将其移动到位置 2^2 .

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


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

  • 1

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

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

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

相关问题