对于逻辑右移操作符有一个线程,但我还没有找到任何逻辑左移操作符。我的问题是,对于任何具有字长w
,整数常数0 <= c < w
和变量int x
和int y
的固定字长语言,
(x+y)<<c = (x<<c) + (y<<c)
?
看起来这应该是正确的,因为所有的加法进位都向左移动,所以向左移动只会损失两边相同的位序列。
如果c >= w
,关系是否为真?
原来我弄明白了。这就是证据
设字长w
为任意值。在此字长范围内选择任意两个有符号变量int x
和int y
,令整型常数c
满足0 <= c < w
。定义两个新变量int xW2
和int yW2
,使它们可以存储长度为2*w + 1
的位序列。将x
和y
的位序列复制到xW2
和yW2
中,使xW2 = x
和yW2 = y
具有相等的值。xW2 << c
和yW2 << 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)<<c
、x<<c
、y<<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
希望这是很好的解释:)