¿Cómo puedo extraer los bits de 32 bits número de

Que tengo no tienen mucho conocimiento de C y estoy atascado con un problema, ya que uno de mi colega está de licencia.

Tengo un número de 32 bits y tengo que extraer los bits de ella. Me hizo ir a través de un par de hilos, pero im todavía no está claro cómo hacerlo. Yo estaría muy agradecido si alguien me puede ayudar.

Aquí es un ejemplo de lo que debo hacer:

Asumir número hexadecimal= 0xD7448EAB.
En binario= 1101 0111 0100 0100 1000 1110 1010 1011
Necesito extraer de 16 bits, y la salida de ese valor. Quiero bits de 10 a 25 años.

El menor de 10 bits (Decimal) son ignorados. es decir,10 1010 1011 son ignorados.

Y en la parte superior de 6 bits (Desbordamiento) son ignorados. es decir, 1101 01 son ignorados.

El resto de los 16 bits de datos debe ser la salida que es a las 11 0100 0100 1000(los números en cursiva son necesarios como el de salida).

Este fue un ejemplo, pero voy a seguir recibiendo diferentes números hexadecimales todo el tiempo y tengo que extraer la misma bits como he explicado.

¿Cómo puedo solucionar esto?

Gracias.

Para este ejemplo sería la salida de 1101 0001 0010 0011, que es 0xD123, o 53,539 decimal.

  • ¿Usted necesita para mantener todo en forma binaria? O tendría que ser capaz de convertir el valor hexadecimal a binario, luego de convertir el valor binario en una cadena. Entonces, usted puede simplemente tomar la subcadena que usted está interesado en, y convertir a binario/hexadecimal como sea necesario.
  • Y (& operador) de su valor con una máscara con el conjunto de bits que usted está interesado en, a continuación, haga mayús el resultado (>> operador) para alinearlos con los bits cero.
InformationsquelleAutor user3267877 | 2014-02-03

4 Kommentare

  1. 2

    Necesita máscaras para obtener los bits que desea. Máscaras son números que se pueden utilizar para tamizar a través de los bits de la manera que usted desea (mantener bits, eliminar/borrar bits, modificar números, etc.). Lo que usted necesita saber son los and, or, XOR, not, y el cambio de operaciones. Para lo que usted necesita, usted sólo necesita un par.

    Sabes cambiando: x << y desplaza los bits de x *y posiciones a la izquierda*.

    Cómo obtener x conjunto de bits a 1 en orden: (1 << x) - 1

    Cómo obtener x conjunto de bits a 1, en orden, a partir de y a y + x: ((1 << x) -1) << y

    El de arriba es su máscara de bits que necesita. Así, por ejemplo, si desea 16 bits de 0xD7448EAB, de 10 a 25, necesitará lo anterior, para x = 16, y = 10.

    Y ahora para obtener los bits que desee, sólo Y su número 0xD7448EAB con la máscara de arriba y obtendrás el enmascarado 0xD7448EAB con sólo los bits que desea. Más tarde, si quieres ir a través de cada uno de ellos, entonces usted necesitará cambiar su resultado por 10 a la derecha y el proceso de cada bit a la vez (en la posición 0).

    La respuesta puede ser un poco más largo, pero es mejor el diseño de difícil codificación con 0xff o lo que sea.

    • Hola webuster, he encontrado el tuyo un poco fácil de entender, así que he intentado calcular el valor pero parece salida de un resultado erróneo. He utilizado los programadores de la calculadora en el modo de hex. 1<<16 = 400000-1= 3fffff. Ahora 3fffff << 10 = 3fffff0000 & D7448eab = D7440000 = 11010111010001000000000000000000 (binario). La salida no es lo que se requiere. Déjeme saber si estoy haciendo algo mal
    • (1 << 16) – 1 = ffff. Lo que estamos haciendo en la Calculadora es Lsh-ing 1 con 16 en HEXADECIMAL, que es de 22 en decimal. Trate de Lsh-ing 1 con 10 en hexadecimal (16 en binario) y obtendrá el resultado correcto.
    • Yo hice eso y el resultado es el mismo (1<<10)-1=ffff <<10 = ffff0000 & 0xD7448EAB = D7440000 = 11010111010001000000000000000000. Los seis primeros bits son para ser ignorado y si comprueba que no están siendo ignorados y por lo tanto el resultado incorrecto. El resultado que necesita es 1101 0001 0010 0011
    • Estaban haciendo el mismo error, Lsh-ing y Rsh-ción con base 16 no en decimal. Lsh-ción con 10 en HEXADECIMAL significa cambiar por 16. El dígito Hex para el 10 decimal es A. Así que la forma en que debe cambiar es FFFF << A. Así que los pasos son (con respecto a la Calculadora): 1 << 10, entonces -1 => FFFF. Luego FFFF << a = 3FFFC00. Luego D7448EAB & 3FFFC00 es 3448C00 que en binario es 1101 0001 0010 0011 como usted quería.
    • Tal vez una pregunta tonta, pero estoy sinceramente un novato cuando se trata de C. puede utilizar esta expresión – ((1 << 10) -1) << a en el código C, ¿correcto? No hay ninguna diferencia entre el C y el que usamos para la calculadora?
    • Nono. En C, el «default» numérico de base decimal, no se hex. Por lo que se podría hacer ((1 << 16) – 1) << 10) como en mi respuesta, que sería su máscara. A continuación, Y su número con la máscara y obtendrá el resultado correcto. SI desea utilizar hex y como hizo con la calculadora, poner 0x delante de los números, como en ((1 << 0 x 10) – 1) << 0xA). La máscara es equivalente.
    • Webbuster esto era bastante útil. Muchas gracias

  2. 3

    OK, aquí está cómo lo escribí:

    #include <stdint.h>
    #include <stdio.h>
    
    main() {
        uint32_t in = 0xd7448eab;
        uint16_t out = 0;
    
        out = in >> 10; //Shift right 10 bits
        out &= 0xffff;  //Only lower 16 bits
        printf("%x\n",out);
    }
    

    La in >> 10 cambia el número de 10 bits; el & 0xffff descarta todos los bits a excepción de los 16 bits inferiores.

    • ¿Por qué utilizar = y &= por separado, en lugar de utilizar = y & en la misma declaración?
    • Más simples a seguir para un principiante en C (que me deja comentar cada cambio) y & tiene precedente cuestiones (que puede realmente deshacerse de alguien que no sabe que las cuerdas de C)
    • ¿Cómo podría adaptar esta solución para extraer una variedad desconocida de bits? Como una función extract(unsigned num, unsigned hi, unsigned lo) que devuelve los bits en el rango hi a lo de num?
  3. 1

    Quiero bits de 10 a 25 años.

    Usted puede hacer esto:

    unsigned int number = 0xD7448EAB;
    unsigned int value = (number & 0x3FFFC00) >> 10;
    

    O este:

    unsigned int number = 0xD7448EAB;
    unsigned int value = (number >> 10) & 0xFFFF;
    
    • unsigned int numero = 0xD7448EAB; unsigned int valor = (número de & 0x3FFFC00) >> 10; esto es absolutamente correcto. el único cambio necesario es >>8 en lugar de >>10. Tengo este trabajo. Gracias
    • El uso de >> 10 es correcto para lo que usted pidió. El uso de >> 8 te de bits de 8 a 23, que no es lo que usted pidió.
  4. 1

    He combinado el top 2 de las respuestas de arriba para escribir un programa en C que los extractos de los bits para cualquier rango de bits (no sólo de 10 a 25 años) de 32-bit unsigned int. La forma de la función de las obras es que devuelve bits lo a hi (inclusive) de num.

    #include <stdio.h>
    #include <stdint.h>
    
    unsigned extract(unsigned num, unsigned hi, unsigned lo) {
        uint32_t range = (hi - lo + 1);  //number of bits to be extracted
        //shifting a number by the number of bits it has produces inconsistent 
        //results across machines so we need a special case for extract(num, 31, 0)
        if(range == 32)
            return num;
        uint32_t result = 0;
        //following the rule above, ((1 << x) - 1) << y) makes the mask:
        uint32_t mask = ((1 << range) -1) << lo;
        //AND num and mask to get only the bits in our range
        result = num & mask;
        result = result >> lo; //gets rid of trailing 0s
        return result;
    }
    int main() {
        unsigned int num = 0xd7448eab;
        printf("0x%x\n", extract(num, 10, 25));
    }
    

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea