2010-04-12 5 views
7

Dado dos enteros X e Y, quiero sobreescribir los bits en la posición P a P + N.Sobrescribir un rango de bits en un entero de forma genérica

Ejemplo:

int x  = 0xAAAA; // 0b1010101010101010 
int y  = 0x0C30; // 0b0000110000110000 
int result = 0xAC3A; // 0b1010110000111010 

¿Este procedimiento tiene un nombre?

Si tengo máscaras, la operación es bastante fácil:

int mask_x = 0xF00F; // 0b1111000000001111 
int mask_y = 0x0FF0; // 0b0000111111110000 
int result = (x & mask_x) | (y & mask_y); 

Lo que no acabo de entender es la forma de escribir de una manera genérica, como en la siguiente función genérica de C++:

template<typename IntType> 
IntType OverwriteBits(IntType dst, IntType src, int pos, int len) { 
// If: 
// dst = 0xAAAA; // 0b1010101010101010 
// src = 0x0C30; // 0b0000110000110000 
// pos = 4      ^
// len = 8    ^------- 
// Then: 
// result = 0xAC3A; // 0b1010110000111010 
} 

El problema es que no puedo entender cómo hacer las máscaras correctamente cuando todas las variables, incluido el ancho del entero, son variables.

¿Alguien sabe cómo escribir la función anterior correctamente?

Respuesta

8

Un poco el cambio le dará las máscaras que necesita.

template<typename IntType> 
IntType OverwriteBits(IntType dst, IntType src, int pos, int len) { 
    IntType mask = (((IntType)1 << len) - 1) << pos; 
    return (dst & ~mask) | (src & mask); 
} 
+1

¿Necesita esto un caso especial para cuando está enmascarando toda la cuerda? Como en ese caso, 1 << len se desbordará. –

+0

Realmente se desbordará, pero dará la respuesta correcta. –

0

Puede crear las máscaras usando:

int mask_y = ((1 << len) - 1) << pos; 
int mask_x = ~mask_y; 
+2

Esto no funcionará si '' IntType' es un long' larga (en la mayoría de los sistemas). –

0

Hacer la máscara para las posiciones P a P + N tomando ((2^N + 1) - 1) < < P ??

2^(N + 1) le da un 1 en la posición N + 1, Suntracting 1 establece todos los primeros N bits, y luego a la izquierda cambiando P veces mueve enteros las posiciones disposición P ...

Desde 2^N se equivilent a 1 desplazamiento a la izquierda N veces, todo el asunto se hace por:

((1 << (N+1)) -1) << P 

el N y el P puede ser apagado por uno, pero generalmente, esto debería funcionar

Cuestiones relacionadas