2010-09-28 15 views
9

Necesito convertir bytes en formato de complemento a dos bytes enteros positivos. El rango de -128 a 127 asigna a 0 a 255.Conversión de complemento a dos

Examples: -128 (10000000) -> 0 , 127 (01111111) -> 255, etc. 

EDITAR Para aclarar la confusión, el byte de entrada es (por supuesto) un entero sin signo en el intervalo de 0 a 255. Pero representa un entero con signo en el rango -128 a 127 usando el formato de complemento de dos. Por ejemplo, el valor del byte de entrada de 128 (binario 10000000) representa en realidad -128.

EXTRA EDIT De acuerdo, digamos que tenemos el siguiente byte de flujo 0,255,254,1,127. En el formato de complemento a dos, esto representa 0, -1, -2, 1, 127. Esto necesito sujetarlo al rango de 0 a 255. Para obtener más información echa un vistazo a este duro encontrar el artículo: Two's complement

+2

'byte' no esté firmado, ¿qué estás tratando de hacer? – leppie

+0

Todavía no estoy completamente seguro de qué se intenta aquí. O bien es la forma en que todas las respuestas te dan, o estás entendiendo la representación del complemento de 2 incorrectamente. – leppie

Respuesta

7

Desde que muestra de entrada simplemente desea:

sbyte something = -128; 

byte foo = (byte)(something + 128); 
+0

Por favor, vea mis ediciones. Espero que esté más claro ahora. – Yehonatan

+3

@Yehonatan: ¿Pero cómo quieres representar -1 en el rango de 0 a 255? – leppie

0

Usted podría describir algo tan simple como añadir un sesgo a su número (en este caso, agregando 128 al número firmado).

+0

Si fuera así de simple. – Yehonatan

6
new = old + 128; 

bingo :-)

+9

dado que no pude encontrar la palabra clave 'bingo', he editado su respuesta para que sea legible :-) – paxdiablo

+0

¿Es 'viejo' el valor del byte original o la conversión del mismo? Si es el valor del byte original, esto da la respuesta incorrecta. Si es el último, entonces ese es el proceso, es lo que estoy pidiendo. – Yehonatan

0

Si undestood correctamente, el problema es cómo convertir la entrada, que es realmente un signed-byte (sbyte), pero que de entrada se almacena en un unsigned integer, y luego también evite los valores negativos convirtiéndolos a cero.

Para ser claros, cuando utiliza un tipo con signo (como ubyte) el marco está usando Two's complement detrás de la escena, por lo que solo con el tipo correcto usará el complemento de dos.

Luego, una vez que haya realizado la conversión, puede fijar los valores negativos con un simple if o un operador ternario condicional (?:).

Las funciones se presentan a continuación volverá 0 para valores from 128 to 255 (o desde -128 a -1), y the same value para valores from 0 to 127.

lo tanto, si mosto uso de enteros sin signo como entrada y salida que podría utilizar algo como esto:

private static uint ConvertSByteToByte(uint input) 
{ 
    sbyte properDataType = (sbyte)input; //128..255 will be taken as -128..-1 
    if (properDataType < 0) { return 0; } //when negative just return 0 
    if (input > 255) { return 0; } //just in case as uint can be greater than 255 
    return input; 
} 

O, en mi humilde opinión, que podría cambiar su entrada y salidas de los tipos de datos que mejor se adapten a su entrada y salida (sbyte y el byte):

private static byte ConvertSByteToByte(sbyte input) 
{ 
    return input < 0 ? (byte)0 : (byte)input; 
} 
2

Trate

sbyte signed = (sbyte)input; 

o

int signed = input | 0xFFFFFF00; 
1
public static byte MakeHexSigned(byte value) 
    { 
     if (value > 255/2) 
     { 
      value = -1 * (255 + 1) + value; 
     } 

     return value; 
    } 
1
int8_t indata; /* -128,-127,...-1,0,1,...127 */ 
uint8_t byte = indata^0x80; 

XOR MSB, eso es todo

+2

Eso no se parece a C# para mí – reggaeguitar

0

Creo que complementan 2s bytes se hace mejor con la siguiente. Tal vez no elegante o corto, pero claro y obvio. Lo pondría como un método estático en una de mis clases de utilidades.

public static sbyte ConvertTo2Complement(byte b) 
{ 
    if(b < 128) 
    { 
     return Convert.ToSByte(b); 
    } 
    else 
    { 
     int x = Convert.ToInt32(b); 
     return Convert.ToSByte(x - 256); 
    } 
} 
1

Aquí está mi solución para este problema, para números mayores que 8 bits. Mi ejemplo es para un valor de 16 bits. Nota: Deberá verificar el primer bit para ver si es negativo o no.

Pasos:

  1. Convertir # Para complementar mediante la colocación de '~' antes variable. (Es decir. ~ Y = y)

  2. Conversor #s a cadena binaria

  3. rotura cadenas binarias en una matriz de caracteres

  4. A partir de derecho más valor, añadir 1, hacer el seguimiento de acarreos. Almacenar el resultado en la matriz de caracteres.

  5. Convertir character array a string.

    private string TwosComplimentMath(string value1, string value2) 
    { 
        char[] binary1 = value1.ToCharArray(); 
        char[] binary2 = value2.ToCharArray(); 
        bool carry = false; 
        char[] calcResult = new char[16]; 
    
        for (int i = 15; i >= 0; i--) 
        { 
         if (binary1[i] == binary2[i]) 
         { 
          if (binary1[i] == '1') 
          { 
           if (carry) 
           { 
            calcResult[i] = '1'; 
            carry = true; 
           } 
           else 
           { 
            calcResult[i] = '0'; 
            carry = true; 
           } 
          } 
          else 
          { 
           if (carry) 
           { 
            calcResult[i] = '1'; 
            carry = false; 
           } 
           else 
           { 
            calcResult[i] = '0'; 
            carry = false; 
           } 
          } 
         } 
         else 
         { 
          if (carry) 
          { 
           calcResult[i] = '0'; 
           carry = true; 
          } 
          else 
          { 
           calcResult[i] = '1'; 
           carry = false; 
          } 
         } 
    
        } 
    
        string result = new string(calcResult); 
        return result; 
    
    }