Pergunta

Eu estou escrevendo uma função getBits curtas (dados curtos, p int, int n)

Eu tentei:

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;
}

Isso funciona para getBits ((short) 0x7000, 0, 4), mas se eu fosse para substituir a 7 com um 8 eu recebo um valor negativo.

Foi útil?

Solução

Existem algumas coisas para se lembrar sobre tipos de dados java, para fazer a coisa funcionar.

Eu estou supondo que você está usando variáveis ??int por causa da ausência de conversões explícitas em sua expressão. Se você estiver usando um tipo int para as suas variáveis: start_pos de dados e comprimento; você deve usar 32 em vez de 16, desde de int são valores de 32 bits.

Além disso, se você estiver indo para usar um inteiro tipos primitivos como int, short ou byte, lembre-se que estes tipos primitivos são complemento de dois que são estendidas-sinal, o que significa que se você fizer um deslocamento para a direita em números negativos como ~ 0 ( avalia a -1), os será acrescentada sobre o bit de ordem mais elevada (bit de sinal) em vez de zeros.

Por exemplo:

1111 1111 1111 1111 1111 1111 1111 1000        
>>1
1111 1111 1111 1111 1111 1111 1111 1100 

Agora, voltando para o seu problema. A ideia geral é a de ser capaz de fazer uma:

data & mask

Agora, gerando a máscara é um pouco complicado em tipos de dados assinados. Não faria sentido para gerar a máscara usando:

(~0 << (32 - length) >> (32 - length - start_pos))

Mas isso não vai funcionar, claro, por causa da extensão de sinal.

Gostaria de sugerir que em vez de usar shift direita >>, usar o operador de rotação >>> dessa forma, em vez de que estão sendo anexados sobre o bit de ordem superior, o operador girar irá anexar o bit de ordem inferior.

Por exemplo:

1111 1111 1111 1111 1111 1111 1111 1000        
>>>1
0111 1111 1111 1111 1111 1111 1111 1100 

então ...

mask = (~0 << 32-length >>> 32-length-start_pos)

E sua resposta final seria algo parecido com:

(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos

A operação de rotação externa move seus dados mascarados para os bits de ordem inferior.

Outras dicas

Não sei por que você precisa usar short. Aqui está uma solução usando por muito tempo.

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);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top