Pregunta

Estoy escribiendo una función getbits cortos (datos cortas, p int, int n)

He tratado:

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

Esto funciona para getbits (0x7000 (cortas), 0, 4), pero si tuviera que reemplazar el 7 con un 8 consigo un valor negativo.

¿Fue útil?

Solución

Hay algunas cosas que debe recordar acerca de los tipos de datos de Java, para que esto funcione.

Te estoy suponiendo que está utilizando variables int debido a la ausencia de conversiones explícitas en su expresión. Si está utilizando un tipo int para sus variables: start_pos de datos y longitud; usted debe utilizar 32 en lugar de 16, ya que de INT son valores de 32 bits.

Además, si usted va a utilizar tipos de enteros primitivos como int, corta o byte, recuerde que estos tipos primitivos son el complemento a dos que son de signo extendido, lo que significa que si lo hace un desplazamiento a la derecha de los números negativos como ~ 0 ( evalúa a -1), los se añadirán en el más alto orden de bits (bit de signo) en lugar de ceros.

Por ejemplo:

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

Ahora volviendo a su problema. La idea general es ser capaz de hacer un:

data & mask

Ahora, la generación de la máscara es un poco complicado en tipos de datos firmados. No tendría sentido para generar la máscara usando:

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

Pero esto no funcionará, por supuesto, debido a la extensión de signo.

Yo sugeriría que en vez de usar desplazamiento a la derecha >>, gire el uso del operador >>> esa manera en lugar de los que se adjunta en el bit de orden superior, el operador de rotación añadirá el bit de orden inferior.

Por ejemplo:

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

así que ...

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

Y su respuesta final sería algo como:

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

La operación de rotación más externa mueve sus datos enmascarados a los bits de orden inferior.

Otros consejos

No sé por qué es necesario utilizar corto. Aquí es una solución de largo usando.

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top