• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

352
Vistas
Dada una máscara de bits, cómo calcular el recuento de desplazamiento de bits

Me gustaría tener una función o (preferiblemente) una macro que calcule la cantidad de turnos necesarios para obtener una determinada máscara de bits.

Actualmente hago algo como:

 #define CURRBITMASK 0x30 #define CURRBITSHIFT 4

Lo que quiero hacer:

 #define BITMASK1 0x10 #define BITSHIFT1 GETSHIFT(BITMASK1) // 4 ; 0x10 = (0x1 << 4) #define BITMASK2 0x18 #define BITSHIFT2 GETSHIFT(BITMASK2) // 3 ; 0x18 = (0x3 << 3) #define BITMASK3 0xC0 #define BITSHIFT3 GETSHIFT(BITMASK3) // 6 ; 0xC0 = (0x3 << 6) #define BITMASK4 0x40 #define BITSHIFT4 GETSHIFT(BITMASK3) // 6 ; 0x40 = (0x1 << 6)

¿Hay alguna forma de obtener el cambio requerido de la máscara usando solo una macro? Si no, ¿hay una forma más óptima de hacerlo como una función que esta?:

 int get_shift(int bitmask) { int count = 0; while (bitmask & 0x1) { bitmask >>= 1; count++; } return count; }
over 3 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Su implementación es equivalente a contar la cantidad de ceros finales en un número.

Hay varias maneras de hacer esto descritas aquí . Uno de los ejemplos hace esto en siete pasos para un número de 32 bits:

 unsigned int v; // 32-bit word input to count zero bits on right unsigned int c = 32; // c will be the number of zero bits on the right v &= -signed(v); if (v) c--; if (v & 0x0000FFFF) c -= 16; if (v & 0x00FF00FF) c -= 8; if (v & 0x0F0F0F0F) c -= 4; if (v & 0x33333333) c -= 2; if (v & 0x55555555) c -= 1;
over 3 years ago · Santiago Trujillo Denunciar

0

Esta respuesta a una pregunta mía da una solución macro:

 /* Number of bits in inttype_MAX, or in any (1<<b)-1 where 0 <= b < 3E+10 */ #define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) /0x3fffffffL %0x3fffffffL *30 \ + (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4-12/((m)%31+3))

o si quiere más simple y no le importan los números enteros> 2040 bits:

 /* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */ #define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))

Para su uso, la m que desea pasar es (x&-x)-1 . x&-x quita todo menos el bit más bajo de x , lo que produce una potencia de dos, y luego restando 1 lo pone en la forma correcta para estas macros.

La respuesta vinculada vincula a una publicación de Usenet sobre cómo funciona.

over 3 years ago · Santiago Trujillo Denunciar

0

He creado una solución rápida que no necesita pasos iterativos. Sin embargo, nunca se sabe la cantidad de bits a desplazar, sino la enésima potencia del desplazamiento. Luego, el cambio se realiza a través de la multiplicación/división, que el compilador optimizará como cambios de bits.

 #define BITS2SHIFT(mask) (mask&-mask) #define MOV2MASK(val,mask) (val*BITS2SHIFT(mask))&mask #define MASK2VAL(val,mask) (val&mask)/BITS2SHIFT(mask)

Vea este ejemplo sobre cómo usarlo.

over 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda