简体   繁体   English

Java表达式等效

[英]Java expression equivalence

For Java how is: 对于Java,如何:

long c = ((long)a << 32) | ((long)b & 0xFFFFFFFL);

equivalent to 相当于

long c = (long)a << 32
c+=b

The bit mask as I understand it will give back the original number itself and the OR and the addition operation are not equivalent. 据我了解,位掩码将返回原始数字本身,并且OR和加法运算不等效。 How then do these two implementations always give the same answer? 那么这两个实现如何始终给出相同的答案?

Bitwise OR is equivalent to addition, if the operands do not have any common bits. 如果操作数没有任何公共位,则按位或等效于加法。

For example: 例如:

0x123456780000000 + 0x12345678 = 0x1234567812345678
0x123456780000000 | 0x12345678 = 0x1234567812345678

If you just shifted a 32 bits to the left, there will be 32 zero bits on the right. 如果你只是转移a 32位的左侧,会出现在右侧32个零位。 Assuming b has only 32 bits you can safely do OR instead of addition. 假设b只有32位,则可以安全地执行“或”运算而不是加法运算。

They're not equivalent (unless you restrict the possible values of b ). 它们不是等效的(除非您限制b的可能值)。

For example, if a == 1 and b == -1, the first expression results in 4563402751 and the second expression results in 4294967295 . 例如,如果a == 1和b == -1,则第一个表达式的结果为4563402751 ,第二个表达式的结果为4294967295

They will give the same result if you limit b to be >= 0 and <= 0xFFFFFFF (which is 2^28 - 1 ). 如果将b限制为> = 0和<= 0xFFFFFFF2^28 - 1 0xFFFFFFF ,它们将给出相同的结果。

(long)a << 32 (assuming a is of a smaller primitive type than long ) shifts the bits of a 32 positions to the left. (long)a << 32 (假设a是一个较小的原始类型比long )移位的位a 32个位置的左边。

Therefore if a was 因此,如果a

                          xxx....xxxxxx

(long)a << 32 is (长)a << 32是

             xxx....xxxxxx000....000000 

Now if you perform bitwise OR between this number and any non-negative int , you'll get the same result as adding those two numbers, since the low 32 bits of (long)a << 32 are 0, so adding to it a number that only has 1 bits in its low 31 bits is the same as setting to 1 all the bits that are 1 in (long)a << 32 and all the bits the are 1 in the second number (which is equivalent to bitwise OR). 现在,如果您在此数字与任何非负int之间执行按位或运算,您将获得与将这两个数字相加的结果,因为(long)a << 32的低32位为0,因此将其加到在其低31位中仅包含1位的数字与将(long)a << 32所有为1的位和将第二个数字中所有为1的位设置为1相同(相当于按位或)。

Let's look at the bits. 让我们看看这些位。

Suppose int is 1 byte (8 bits) and long is 2 bytes (16 bits). 假设int是1个字节(8位),而long是2个字节(16位)。

The a << 32 becomes a << 8 and 0xFFFFFFFFL becomes 0xFFFFL : a << 32变成a << 80xFFFFFFFFL变为0xFFFFL

Left part ( (long)a << 8 ): 左部分( (long)a << 8 ):

Start: 开始:

bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: a a a a a a a a a a a a a a a a

Shift a << 8 : 移位a << 8

                      <-  shifted  ->
bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: a a a a a a a a 0 0 0 0 0 0 0 0

Right part ((long)b & 0xFFFFL) : 右侧((long)b & 0xFFFFL)

Start: 开始:

bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: b b b b b b b b b b b b b b b b

After b & 0xFFFL : b & 0xFFFL

      <- & with 0  -> <- & with 1  ->
bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: 0 0 0 0 0 0 0 0 b b b b b b b b

And now | 而现在| (note that a and b do not "touch" each other!): (请注意, ab不会彼此“接触”!):

bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: 0 0 0 0 0 0 0 0 b b b b b b b b

bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: a a a a a a a a 0 0 0 0 0 0 0 0

Gives: 得到:

bits: 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
data: a a a a a a a a b b b b b b b b

Note that this will probably work only for a subset of values (try positive and negative numbers), but the logic behind it is as I stated. 请注意,这可能仅适用于值的子集(尝试正数和负数),但是其背后的逻辑如我所述。

((long)b & 0xFFFFFFFFL) extracts the least significant 32 bits from b . ((long)b & 0xFFFFFFFFL)b提取最低有效32位。 ((long)a << 32) creates a long where the least significant 32 bits are 0. This way, the OR is equivalent to += . ((long)a << 32)创建一个long,其中最低有效32位为0。这样,OR等于+=

I am not sure if this also works for negative values of b, though (two's complement). 我不确定这是否也适用于b的负值(二进制补码)。

Please note that long in Java has 64 bits. 请注意,Java中的long具有64位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM