함수 작성 : 짧은 getbits (짧은 데이터, int p, int n)
문제
나는 짧은 getbits (짧은 데이터, int p, int n)를 작성하고 있습니다.
나는 시도했다 :
public static short getBits(short data, int p, int n) {
short bitmask = (short) ((~0 << (16 -n)) >>> p);
short returnVal = (short) ((bitmask & data) >>> (16 - n));
return returnVal;
}
이것은 getBits ((짧은) 0x7000, 0, 4)에서 작동하지만 7을 8로 교체하려면 음수 값을 얻습니다.
해결책
Java 데이터 유형에 대해 기억해야 할 몇 가지가 있습니다.
표현에 명시적인 캐스트가 없기 때문에 Int 변수를 사용하고 있다고 가정합니다. 변수에 int 유형을 사용하는 경우 : data start_pos 및 length; INT는 32 비트 값이므로 16 대신 32를 사용해야합니다.
또한 int, short 또는 byte와 같은 정수 원시 유형을 사용하려면 이러한 원시 유형은 부호 확장 된 두 보완 물이므로 ~ 0과 같은 음수로 올바른 전환을하는 경우 ( -평가합니다. 1), 하나는 0 대신 고차 비트 (부호 비트)에 추가됩니다.
예를 들어:
1111 1111 1111 1111 1111 1111 1111 1000
>>1
1111 1111 1111 1111 1111 1111 1111 1100
이제 문제로 돌아갑니다. 일반적인 아이디어는 다음을 수행 할 수 있다는 것입니다.
data & mask
이제 마스크를 생성하는 것은 서명 된 데이터 유형에서 약간 까다로워집니다. 다음을 사용하여 마스크를 생성하는 것이 합리적입니다.
(~0 << (32 - length) >> (32 - length - start_pos))
그러나 이것은 부호 확장으로 인해 작동하지 않습니다.
오른쪽 편이 >>를 사용하는 대신 ROTATE 연산자 >>>를 사용하는 대신 고차 비트에 추가되는 대신 회전 연산자가 더 낮은 주문 비트를 추가 할 것을 제안합니다.
예를 들어:
1111 1111 1111 1111 1111 1111 1111 1000
>>>1
0111 1111 1111 1111 1111 1111 1111 1100
그래서...
mask = (~0 << 32-length >>> 32-length-start_pos)
그리고 당신의 마지막 답변은 다음과 같습니다.
(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos
가장 바깥 쪽 회전 작업은 마스크 된 데이터를 하위 주문 비트로 이동시킵니다.
다른 팁
왜 짧게 사용 해야하는지 잘 모르겠습니다. 다음은 Long을 사용하는 솔루션입니다.
public static long getBits(long data, int p, int n) {
assert p >= 0 && p < 64;
assert n >= 0 && n < 64;
return (data >> p) & ((1 << n) - 1);
}