Cor*_*lks 18 c c++ integer data-representation language-lawyer
我知道C和C++标准没有规定数字的特定表示(可以是二进制补码,符号和数量等).但我不清楚这些标准(并且无法确定是否已经说明)知道在使用位时是否存在任何特定的限制/保证/保留表示.尤其:
x
,我想检查变量y
以查看它是否是第5位是1,我想知道是否if (x & y)
可行(因为据我所知,这取决于表示的值而不是该位是否实际上是1或0))char c
所有位置为真(设置为c = c | ~c
)并c = c << (CHAR_BIT - 1)
设置高位和c = c ^ (c << 1)
低位更简单的方法,假设我没有做任何假设,我不应该这样,给出这些问题)我想我的整体问题是:C和C++标准是否有关于位和整数的限制/保证/保留表示,尽管事实上没有强制表示整数的表示(如果C和C++标准在这方面有所不同) ,他们的区别是什么?)
我在完成作业时提出了这些问题,这需要我做一些操作(注意这些不是我作业的问题,这些都是"抽象的").
编辑:至于我称之为"位",我的意思是"值形成"位而不包括"填充"位.
Joh*_*eek 15
(1)如果整数类型中的所有位都为零,则整数整数是否为零?
是的,由全零组成的位模式始终表示0:
整数类型的表示应使用纯二进制计算系统定义值.49 [§3.9.1/ 7]
49使用二进制数字0和1的整数的位置表示,其中由连续位表示的值是加法的,以1开始,并且乘以2的连续积分幂,除了可能对于具有最高位置的位.
(2)如果整数类型中的任何位是1,那么整数整数是否表示非零?(如果这是"是",那么一些表示如符号和幅度将受到额外限制)
实际上,特别允许签名幅度:
[ 例如:本国际标准允许积分类型的2的补码,1的补码和带符号的幅度表示.- 示例 ] [§3.9.1/ 7]
(3)是否有保证的方法来检查是否未设置任何位?
如果考虑签名类型,我相信答案就是"不".它相当于使用所有1的位模式进行相等测试,这只有在您能够生成具有所有1的位模式的带符号数的情况下才有可能.对于无符号数,此表示是有保证的,但如果数字不可表示,则从unsigned转换为signed是未定义的:
如果目标类型已签名,则如果可以在目标类型(和位字段宽度)中表示该值,则该值不会更改; 否则,该值是实现定义的.[§4.7/ 3]
(4)是否有保证检查是否设置了位的方法?
我不这么认为,因为允许有符号幅度-0将比较等于-0.但是应该可以使用无符号数字.
(5)是否有保证的方法来设置最左边和/或最右边的位?
同样,我认为对于无符号数字,答案是"是",对于有符号数字,答案是"否".对于带负号的数字,未定义班次:
否则,如果
E1
有一个带符号的类型和非负值,并且在结果类型中可以表示E1×2 E2,那么这就是结果值; 否则,行为未定义.[§5.8/ 2]
您反复使用术语"所有位",但您没有说明您所指的"所有位".C/C++中整数类型的对象表示可能包括值形成位和填充位.唯一保证不具有填充位的整数类型是[signed/unsigned] char
.
语言总是保证如果所有的值形成位都为零,则表示的整数值也为零.
至于填充位,事情有点复杂.C语言的原始规范(C89/90以及原始C99)并不保证将所有对象位设置为零都会产生有效的整数表示.它可能会产生无效的陷阱表示.即在原始C(甚至在C99中)使用memset(..., 0, ...)
整数类型并不保证对象将接收有效的零值(除了[signed/unsigned] char
).这在后来的规范中有所改变,即在C99的技术勘误之一中.现在要求整数对象中的全零位模式(涉及所有位,包括填充的位)表示有效的零值.
即在现代C中,使用memset(..., 0, ...)
将任何整数对象设置为零是合法的,但它仅在C99之后变得合法.