按位左移运算符分配加法
Bitwise leftshift operator distribute over addition
这里有一个关于逻辑右移运算符的线程,但我还没有找到任何关于逻辑左移运算符的线程。我的问题是对于任何具有字长 w
、整数常量 0 <= c < w
和变量 int x
和 int y
的固定字长语言,[=38= 是真的吗? ]
(x+y)<<c = (x<<c) + (y<<c)
?
看来这应该是正确的,因为所有加法进位都向左移动,所以向左移动应该只会在两边丢失相同的位序列。
如果 c >= w
关系是否成立?
原来我想通了。这是证明
证明
让单词大小 w
任意。在这个word-size内任意选择两个有符号变量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 值,您的定义应该是正确的。
反例:
(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)
是真的,只要c>=0
希望得到很好的解释:)
左移只是乘以 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
...
时有效
is it true that (given 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。
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. C11 §6.5.7 3
An example of undefined behavior is the behavior on integer overflow. C11 §3.4.3 3
这里有一个关于逻辑右移运算符的线程,但我还没有找到任何关于逻辑左移运算符的线程。我的问题是对于任何具有字长 w
、整数常量 0 <= c < w
和变量 int x
和 int y
的固定字长语言,[=38= 是真的吗? ]
(x+y)<<c = (x<<c) + (y<<c)
?
看来这应该是正确的,因为所有加法进位都向左移动,所以向左移动应该只会在两边丢失相同的位序列。
如果 c >= w
关系是否成立?
原来我想通了。这是证明
证明
让单词大小 w
任意。在这个word-size内任意选择两个有符号变量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 值,您的定义应该是正确的。
反例:
(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)
是真的,只要c>=0
希望得到很好的解释:)
左移只是乘以 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
...
is it true that (given
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。
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. C11 §6.5.7 3
An example of undefined behavior is the behavior on integer overflow. C11 §3.4.3 3