对于逻辑右移运算符,有一个线程,但我没有找到任何逻辑右移运算符。我的问题是针对任何字大小为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 :(得分:1)
(给定
是真的吗?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.73
未定义行为的一个示例是整数溢出的行为。 C11§3.4.33
答案 1 :(得分:0)
好吧,对于大于或等于0的c值,你的定义应该是正确的。
反例:
public class MyListView : ListView
{
protected override DependencyObject GetContainerForItemOverride()
{
var container = base.GetContainerForItemOverride();
var da = new DoubleAnimation();
// init da...
var sb = new Storyboard();
// initi sb with container
sb.Begin();
return container;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
var da = new DoubleAnimation();
// init da...
var sb = new Storyboard();
// initi sb with element
sb.Begin();
}
}
其余部分应该与(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
您的定义也适用,那么它只是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)
就是真的
希望这能得到很好的解释:)
答案 2 :(得分:0)
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
...