C++ 标准是否要求有符号整数只有一个符号位?

Does the C++ standard requires signed integers to have exactly one sign bit?

考虑 C++ 的基本有符号整数类型,即:signed charshort intintlong intlong long int,当前的C++ 标准对其底层位表示有要求吗?

他们的位表示的约束是否指定他们应该包括:

这是真的吗?如果不是,那么约束是什么?我正在搜索证明或反驳这一点的标准中的引述。

编辑: 我问这个问题,因为在 C 中,标准说:

6.2.6.2.2:

For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N ). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:

  • the corresponding value with sign bit 0 is negated (sign and magnitude);
  • the sign bit has the value −(2^M ) (two’s complement);
  • the sign bit has the value −(2^M − 1) (ones’complement).

Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for ones’ complement), is a trap representation or a normal value. In the case of sign and magnitude and ones’ complement, if this representation is a normal value it is called a negative zero.

所以我想知道 C++ 中是否存在类似的东西

我猜你问的问题的答案是否定的。

我认为 C++ 标准规定了每个整数类型必须能够表示的最小大小和 值范围。我不认为该标准专门针对您列出的任何限制。

我认为这些都是实施细节。

我认为找到一个 C++ 实现使用多个位来保存符号,而不使用 0 表示正数和 1 表示负数,这会很奇怪。但我不认为 C++ 标准特别要求它。

C++ 标准特别基于写有(6.2.6.2 整数类型)的 C 标准

2 For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit.....

这是 C++11 对有符号整数类型表示的说法:

C++11 N3337 3.9.1 [basic.fundamental] P7:

The representations of integral types shall define values by use of a pure binary numeration system. 49 [ Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. — end example ]

其中脚注 49 内容如下:

  1. A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)

因此,C++ 允许与 C 相同的三个选项,以及满足脚注 49 的任何其他选项。这是 C 允许的超集。然而,根据脚注 49,只允许最高位具有特殊含义。

更新 2021-10-11

C++20 引入了有关允许的有符号整数表示的更改。

N4860 [基本.fundamental/p3] 内容为:

An unsigned integer type has the same object representation, value representation, and alignment requirements (6.7.6) as the corresponding signed integer type. For each value x of a signed integer type, the value of the corresponding unsigned integer type congruent to x modulo 2 N has the same value of corresponding bits in its value representation. 40 [Example: The value −1 of a signed integer type has the same representation as the largest value of the corresponding unsigned type. — end example]

脚注 40 为:

  1. This is also known as two’s complement representation.

因此,C++ 现在要求对有符号整数类型进行二进制补码表示。

要求只有一个符号位意味着必须能够识别一个位,该位对所有负数置位,对所有非负数清零。一个实现可以在 "int" 中包含任意数量的填充位,对它们的值施加任意限制,并将违反这些要求的任何位模式视为陷阱表示,前提是所有产生定义整数值的计算产生的位模式实施将接受。

例如,一个实现可以将 "int" 存储为两个 16 位字,并指定第一个字的 MSB 是符号位。这样的实现可以写入第一个字的 0-14 匹配符号位和 在读取任何不存在的值时陷入陷阱,或使这些位与位匹配 第二个字的 1-15(同样是陷印),或者可以写入任意值 阅读这些位并在阅读时忽略它们,或者做任何其他事情 跟他们。如果一个实现总是把最上面的词写成全部或 全为零,任何位都可以指定为 "sign bit" ,这无关紧要; 其余的都是 "padding bits".

只有一个符号位的要求将主要排除 实现,例如可以任意表示正数 作为位模式 00 或 11,负数作为 01 或 10。在这样的 实施时,有必要检查两位而不是一位 判断一个数是负数还是非负数。