2010-09-28 10 views
9

Ho bisogno di convertire i byte nel formato a complemento a due in byte interi positivi. Il nell'intervallo da -128 a 127 mappato 0 a 255.Conversione del complemento a due

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

EDIT Per chiarire la confusione, il byte di ingresso è (ovviamente) un intero senza segno compreso tra 0 e 255. Ma rappresenta un numero intero con segno compreso nell'intervallo compreso tra -128 e 127 utilizzando il formato complemento a due. Ad esempio, il valore del byte di input di 128 (binario 10000000) rappresenta in realtà -128.

EXTRA EDIT Altrighty, diciamo che abbiamo il seguente flusso di byte 0,255,254,1,127. Nel formato complemento a due questo rappresenta 0, -1, -2, 1, 127. Ciò mi serve per il serraggio nell'intervallo da 0 a 255. Per maggiori informazioni visita questo è difficile trovare un articolo: Two's complement

+2

'byte' non firmato, che cosa stai cercando di fare? – leppie

+0

Non sono ancora completamente sicuro di ciò che viene tentato qui. O è il modo in cui tutte le risposte ti danno, o stai capendo erroneamente la rappresentazione del complemento di 2. – leppie

risposta

7

Da voi campione di ingresso che si desidera semplicemente:

sbyte something = -128; 

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

Si prega di vedere le mie modifiche. Spero che sia più chiaro ora. – Yehonatan

+3

@Yehonatan: Ma come si desidera rappresentare -1 nell'intervallo da 0 a 255? – leppie

0

Si potrebbe essere descrivendo qualcosa di semplice come l'aggiunta di un pregiudizio per il proprio numero (in questo caso, aggiungendo 128 al numero firmato).

+0

Se solo fosse così semplice. – Yehonatan

6
new = old + 128; 

bingo :-)

+9

poiché non sono riuscito a trovare la parola chiave 'bingo', ho modificato la risposta per la leggibilità :-) – paxdiablo

+0

E '" vecchio "il valore del byte originale o la conversione di esso? Se è il valore del byte originale, questo dà la risposta sbagliata. Se è quest'ultimo, allora questo è il processo è ciò che sto chiedendo. – Yehonatan

0

Se comprensione passa correttamente, il problema è come convertire l'ingresso, che è davvero un signed-byte (sbyte), ma che l'input è memorizzato in un unsigned integer, e poi anche evitare valori negativi convertendoli a zero.

Per essere chiari, quando si utilizza un tipo di firma (come ubyte) il quadro sta usando Two's complement dietro la scena, così appena lanciando al giusto tipo che verrà utilizzato a complemento di due.

Quindi, una volta completata la conversione, è possibile bloccare i valori negativi con un semplice if o un operatore ternario condizionale (?:).

Le funzioni presentate di seguito restituirà 0 valori from 128 to 255 (o da -128 a -1), e the same value per valori from 0 to 127.

Quindi, se si must uso numeri interi senza segno come ingresso e uscita si potrebbe usare qualcosa di simile:

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; 
} 

Oppure, secondo me, si potrebbe cambiare il vostro input e output per i tipi di dati più adatti per il vostro ingresso e di uscita (sbyte e byte):

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

Prova

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, questo è tutto

+2

Questo non mi sembra C# – reggaeguitar

0

Credo che 2s complemento byte sarebbe essere meglio fatto con il seguente. Forse non elegante o breve ma chiaro e ovvio. Lo metterei come metodo statico in una delle mie classi util.

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

Ecco la mia soluzione per questo problema, per i numeri più grandi di 8 bit. Il mio esempio è per un valore a 16 bit. Nota: Dovrai controllare il primo bit, per vedere se è negativo o meno.

Passi:

  1. Converti # per complimentarmi mettendo '~' prima variabile. (Es. Y = ~ y)

  2. Convert #s di stringa binaria

  3. Pausa stringhe binarie in array di caratteri

  4. Partendo da destra massimo valore, aggiungere 1, tenendo traccia di porta. Memorizza il risultato nell'array di caratteri.

  5. Converte l'array di caratteri nella stringa.

    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; 
    
    } 
    
Problemi correlati