Extender el signo de una anchura de bits constante en C #
-
09-10-2019 - |
Pregunta
I tiene un valor eso es 5 bits de longitud. 4 bits determinan el número y el quinto bit determina el signo, mediante la celebración de cualquier valor entre -16 y +15. ¿Cómo puedo lograr firmar que se extiende desde un ancho de bits constante en C #? Sé que en C, puedo usar algo así como el seguimiento de lograr esto:
int x; // convert this from using 5 bits to a full int
int r; // resulting sign extended number goes here
struct {signed int x:5;} s;
r = s.x = x;
¿Cómo puedo hacer algo similar a esto en C #?
Solución
En realidad no es claro a qué se refiere, pero podría ser tan simple como:
int fiveBits = normal & 0x1f;
y para el inverso:
int normal = fiveBits < 16 ? fiveBits : fiveBits | -32;
Si usted podría sugerir una cierta entrada original y la salida deseada, eso ayudaría.
Otros consejos
Sé que esto es una cuestión de edad, sino para futuros investigadores no tengo más información.
C # no soporta anchos de bit a medida, pero lo hace de soporte de operaciones binarias y getters / setters, lo que hace que sea relativamente fácil de añadir una capa de compatibilidad. Por ejemplo, si desea almacenar los datos en bruto en un byte _num, pero quiere ser capaz de interactuar con él utilizando un C # sbyte estándar, puede utilizar lo siguiente:
byte _num;
sbyte num {
get
{
return (sbyte)(((_num & 0x10) << 3) | (_num & 0x0F));
}
set
{
_num = (byte)((value & 0x0F) | ((value & 0x80) >> 3));
}
}
Este tipo de cáscara es especialmente útil cuando interactúa con bajo firmware nivel o proyectos embebidos.
Realizar una desviación a la izquierda seguido de un desplazamiento aritmético a la derecha para mover el bit de signo en la posición alta y luego de vuelta. El desplazamiento aritmético a la derecha llevará a cabo la extensión de signo para usted.
Por supuesto, esto depende de tener una operación de desplazamiento aritmético de trabajo. El lenguaje abstracto C no lo hace (que es definido por la implementación si funciona o no), pero la mayoría de las implementaciones hacen. No estoy seguro acerca de C #, pero yo supongo que tiene uno.
Sólo estoy escribiendo una función C (porque no se sabe muy bien C #) que va a hacer esto utilizando las operaciones que sé que están disponibles en C #.
int five_bit_to_signed(int five_bit) {
int sh = (sizeof(int)*8)-5;
int x = five_bit << sh; // puts your sign bit in the highest bit.
return x >> sh; // since x is signed this is an arithmatic signed shift
}
A partir de su pregunta, parece que desea tener una estructura que fácilmente se puede convertir desde y hacia un tipo int
:
struct FiveBit
{
public int bits;
public static implicit operator int(FiveBit f)
{
return (f.bits & 0x10) == 0 ? f.bits : f.bits | -32;
}
public static implicit operator FiveBit(int r)
{
return new FiveBit() { bits = r & 0x1f };
}
}
Y aquí está un ejemplo de uso:
class FiveBitTest
{
static void Main(string[] args)
{
FiveBit f = new FiveBit();
int r; // resulting sign extended number goes here
f.bits = 0;
r = f;
Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
f.bits = 0x1f;
r = f;
Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
r = -2;
f = r;
Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
}
La salida de la anterior es:
r = 0, f.bits = 0x0
r = -1, f.bits = 0x1F
r = -2, f.bits = 0x1E