C语言 位左移运算符分布在加法上



对于逻辑右移操作符有一个线程,但我还没有找到任何逻辑左移操作符。我的问题是,对于任何具有字长w,整数常数0 <= c < w和变量int xint y的固定字长语言,

是否正确?

(x+y)<<c = (x<<c) + (y<<c)

?

看起来这应该是正确的,因为所有的加法进位都向左移动,所以向左移动只会损失两边相同的位序列。

如果c >= w,关系是否为真?

原来我弄明白了。这就是证据

设字长w为任意值。在此字长范围内选择任意两个有符号变量int xint y,令整型常数c满足0 <= c < w。定义两个新变量int xW2int yW2,使它们可以存储长度为2*w + 1的位序列。将xy的位序列复制到xW2yW2中,使xW2 = xyW2 = y具有相等的值。xW2 << cyW2 << c不溢出。此外,(xW2<<c) + (yW2<<c)也不会溢出。但是结果的位序列与xW2 + yW2相同,c的0附加在该和的最低有效位上。因此(xW2 + yW2)<<c = (xW2<<c) + (yW2<<c)。由w-bits截断两个位序列并不违反相等性,因此必须是(x+y)<<c = (x<<c)+(y<<c)

是否(给定0 <= c < w) int x,y; (x+y)<<c = (x<<c) + (y<<c)是真的?

如果c < w为真,且x+y不溢出,(x+y)<<cx<<cy<<c也不溢出,则为真,因为这是一个简单的2次幂的关联乘法。

其他没有。由于有符号整数移位而导致的溢出是未定义的行为。将一个数字移位到UB中的符号位。由于添加是UB而溢出。

如果右操作数的值为负或大于等于提升后的左操作数的宽度,则未定义该行为。C11§6.5.7 3

未定义行为的一个例子是整数溢出时的行为。C11§3.4.3

Leftshift只是乘以2的幂。所以,(x+y)<< c = (x+y)*2^c。为了便于阅读,我们设为C = 2^c。所以,(x+y)<<c = (x+y)* C = Cx + Cy = x<<c + y<<c .

正如其他人所说,这只适用于0 < c < w

好吧,对于大于等于0的c值,您的定义应该是正确的。

反例:

(x+y)<<c = (x<<c) + (y<<c) w=4; c=-1; x=7; y=10; So you got 0111 and 1010: (x<<c) + (y<<c) = 0011 + 0101 = 1000 (x+y)<<c = 0001<<-1 = 0000 <-- the first 1 gets lost in the transaction

剩下的应该和c<w一样长,因为如果它被移到far,两个操作仍然做同样的事情。如果c>=w你的定义将工作得很好,因为它只是一个0==0那么。

的例子:

(x+y)<<c = (x<<c) + (y<<c) w=4; c=4; x=1; y=10; So you got 0001 and 1010: (x<<c) + (y<<c) = 0000 + 0000 = 0000 (x+y)<<c = 0001<<4 = 0000

所以主要规则应该是:

(x+y)<<c = (x<<c) + (y<<c)为真,只要c>=0

希望这是很好的解释:)

最新更新