C 和 C++ 标准对位级整数表示和操作有什么看法?
我知道 C 和 C++ 标准没有规定数字的特定表示(可能是二进制补码、符号和大小等).但是我不太了解这些标准(并且无法找到是否有规定),无法知道在使用位时是否有任何特定的限制/保证/保留表示.特别是:
- 如果一个整数类型的所有位都为零,那么整个整数是否代表零?
- 如果整数类型中的任何一位为1,那么整数作为一个整体是否代表非零?(如果这是是",那么符号和大小等一些表示将受到额外限制)
- 是否有保证的方法来检查是否未设置任何位?
- 是否有可靠的方法来检查是否设置了任何位?(#3 和#4 取决于#1 和#2,因为我知道如何设置,例如某些变量
x
中的第 5 位(参见 #5),我想要检查变量y
以查看它的第 5 位是否为 1,我想知道if (x & y)
是否可以工作(因为据我了解,这取决于表示的值,而不是该位实际上是 1 还是 0)) - 是否有可靠的方法来设置最左边和/或最右边的位?(至少比采用所有位为 true 的
char c
(由c = c | ~c
设置)并执行c = c << (CHAR_BIT - 1)
用于设置高位和c = c ^ (c << 1)
用于低位,假设我没有做任何假设考虑到这些问题,我不应该这样做) - 如果#1 的答案是否",如何遍历整数类型的位并检查每个位是 1 还是 0?
我想我的总体问题是:C 和 C++ 标准对位和整数是否有任何限制/保证/保留表示,尽管整数的表示不是强制性的(并且如果 C 和 C++ 标准不同在这方面,他们有什么区别)?
我在做作业时想出了这些问题,这需要我做一些操作(注意这些不是我作业中的问题,这些问题更抽象").
至于我所说的位",我的意思是价值形成"位,不包括填充"位.
解决方案(1)如果一个整数类型的所有位都为零,那么整个整数是否代表零?
是的,全零组成的位模式总是代表0:
<块引用>整数类型的表示应使用纯二进制计数系统定义值.49 [§3.9.1/7]
49 整数的位置表示,使用二进制数字 0 和 1,其中由连续位表示的值是相加的,从 1 开始,并乘以 2 的连续整数幂,除了位置最高的那位.
<小时><块引用>
(2) 如果整数类型中的任何一位为1,那么整数作为一个整体是否代表非零?(如果这是是",那么像符号和大小这样的一些表示将受到额外限制)
没有.事实上,有符号的幅度是特别允许的:
<块引用>[ 示例: 本国际标准允许整数类型的 2 补码、1 补码和有符号幅度表示.――结束示例 ] [§3.9.1/7]
<小时><块引用>
(3) 是否有保证的方法来检查是否有任何位未设置?
我相信如果您考虑带符号的类型,答案是不".它等同于使用全 1 的位模式进行相等性测试,这只有在您有办法生成具有全 1 的位模式的有符号数时才有可能.对于无符号数,此表示是有保证的,但如果该数不可表示,则从无符号转换为有符号是未定义的:
<块引用>如果目标类型是有符号的,如果它可以在目标类型(和位域宽度)中表示,则值不变;否则,该值是实现定义的.[§4.7/3]
<小时><块引用>
(4) 是否有保证的方法来检查是否设置了任何位?
我不这么认为,因为有符号幅度是允许的――0 比较等于 -0.但是对于无符号数字应该是可能的.
<小时><块引用>(5) 是否有保证设置最左边和/或最右边位的方法?
再一次,我相信对于无符号数字的答案是是",但对于有符号数字,答案是否".负符号数的移位未定义:
<块引用>否则,如果E1
有带符号类型且非负值,且E1 × 2E2在结果类型中是可表示的,那么就是结果值;否则,行为未定义.[§5.8/2]
I know the C and C++ standards don't dictate a particular representation for numbers (could be two's complement, sign-and-magnitude, etc.). But I don't know the standards well enough (and couldn't find if it's stated) to know if there are any particular restrictions/guarantees/reserved representations made when working with bits. Particularly:
- If all the bits in an integer type are zero, does the integer as whole represent zero?
- If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
- Is there a guaranteed way to check if any bit is not set?
- Is there a guaranteed way to check if any bit is set? (#3 and #4 kind of depend on #1 and #2, because I know how to set, for example the 5th bit (see #5) in some variable
x
, and I'd like to check a variabley
to see if it's 5th bit is 1, I would like to know ifif (x & y)
will work (because as I understand, this relies on the value of the representation and not whether nor not that bit is actually 1 or 0)) - Is there a guaranteed way to set the left-most and/or right-most bits? (At least a simpler way than taking a
char c
with all bits true (set byc = c | ~c
) and doingc = c << (CHAR_BIT - 1)
for setting the high-bit andc = c ^ (c << 1)
for the low-bit, assuming I'm not making any assumptions I should't be, given these questions) - If the answer to #1 is "no" how could one iterate over the bits in an integer type and check if each one was a 1 or a 0?
I guess my overall question is: are there any restrictions/guarantees/reserved representations made by the C and C++ standards regarding bits and integers, despite the fact that an integer's representation is not mandated (and if the C and C++ standards differ in this regard, what's their difference)?
I came up with these questions while doing my homework which required me to do some bit manipulating (note these aren't questions from my homework, these are much more "abstract").
Edit: As to what I refer to as "bits," I mean "value forming" bits and am not including "padding" bits.
解决方案(1) If all the bits in an integer type are zero, does the integer as whole represent zero?
Yes, the bit pattern consisting of all zeroes always represents 0:
The representations of integral types shall define values by use of a pure binary numeration system.49 [§3.9.1/7]
49 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.
(2) If any bit in an integer type is one, does the integer as a whole represent non-zero? (if this is a "yes" then some representations like sign-and-magnitude would be additionally restricted)
No. In fact, signed magnitude is specifically allowed:
[ Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. ―end example ] [§3.9.1/7]
(3) Is there a guaranteed way to check if any bit is not set?
I believe the answer to this is "no," if you consider signed types. It is equivalent to equality testing with a bit pattern of all ones, which is only possible if you have a way to produce a signed number with bit pattern of all ones. For an unsigned number this representation is guaranteed, but casting from unsigned to signed is undefined if the number is unrepresentable:
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined. [§4.7/3]
(4) Is there a guaranteed way to check if any bit is set?
I don't think so, because signed magnitude is allowed―0 would compare equal to ?0. But it should be possible with unsigned numbers.
(5) Is there a guaranteed way to set the left-most and/or right-most bits?
Again, I believe the answer is "yes" for unsigned numbers, but "no" for signed numbers. Shifts are undefined for negative signed numbers:
Otherwise, if
E1
has a signed type and non-negative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined. [§5.8/2]
相关文章