Java hex calculation

不问归期 提交于 2020-01-05 08:20:56

问题


I have the long value bits declared like so:

long bits = len*8L; (304)

System.out.println(bits); This outputs as 304

If I use the long name bits like so I get 0 & 0 respectively.

System.out.println(bits>>(4*8));
System.out.println(0xFF&(bits>>(4*8)));

If I use the actual number, like so, I get 304 and 48 respectively

System.out.println(304>>(4*8));
System.out.println(0xFF&(304>>(4*8)));

I'm trying to convert this Java to JavaScript but JavaScript gives me 304 and 48 in all scenarios. I need it to match the Java and give values of 0 & 0.

Any ideas?

EDIT

Follow up, just to be clear, I need the JavaScript equivalent to equal 0, mimicking how the Java currently does it (the two examples above that equal 0 won't be changed in what we're developing).

So console.log(0xFF&(bits>>(4*8))) should equal 0, it currently equates to 48


回答1:


The JLS, Section 15.19 covers shifting operators in Java.

If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

For an int value such as 304, the bit shift value of 4*8, or 32, is really 0, so no shifting takes place. Then a bit-and with 0xFF yields 48.

If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x3f (0b111111). The shift distance actually used is therefore always in the range 0 to 63, inclusive.

For a long value, the bit shift value of 4*8 really does shift to the right 32 bits, which yields 0.

This page covers JavaScript bit-shift operators.

Bitwise operators treat their operands as a sequence of 32 bits (zeroes and ones), rather than as decimal, hexadecimal, or octal numbers.

It appears that JavaScript converts the number to a 32-bit number, like a Java int. It also appears that the same "only the least 5 bits" rule applies to the shift operand in JavaScript also.

console.log(304>>32);        // Don't shift!
console.log(0xFF&(304>>32)); // Don't shift!
console.log(304>>33);        // Shift by 1, not 33
console.log(0xFF&(304>>33)); // Shift by 1, not 33



回答2:


If you want to get the same result with constants in Java as with variables, you need to pass 304 as a long constant with 304L, like this:

System.out.println(304L>>(4*8));
System.out.println(0xFF&(304L>>(4*8)));

The reason is that you cannot shift an int with 4*8=32 bits; Java will shift 32 modulo 32 = zero buts, since an int is only 32 bits long.

Javascript, in constrast, doesn't support shifting 64-bit integers with the >> operator; it treats every number that you pass to >> as a 32-bit integer.

You could write your own function that does something similar:

function rshift(num, bits) {
    return Math.round(num / Math.pow(2,bits));
}

console.log(rshift(304, 4*8))


来源:https://stackoverflow.com/questions/53291811/java-hex-calculation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!