2011-08-18 14 views
5

Voglio convertire un int a un array di byte [4] usando BCD.Conversione di un array di byte Int a BCD

L'int in questione verrà da un id del dispositivo e il suo necessario per parlare a un dispositivo tramite porta seriale.

Esiste una funzione preimpostata che esegue questo o puoi darmi un modo semplice per farlo?

esempio:

int id= 29068082 

visualizzerà:

byte[4]{0x82, 0x80, 0x06, 0x29}; 
+0

Suppongo tu intenda "0x29}"? –

+0

Non so di alcun supporto BCD in lib, la tua migliore scommessa è una funzione personalizzata che usa ToString come intermedio. –

+0

Sì, dovrebbe essere 0x29 scusa .. – Kingpin

risposta

7

Utilizzare questo metodo.

public static byte[] ToBcd(int value){ 
     if(value<0 || value>99999999) 
      throw new ArgumentOutOfRangeException("value"); 
     byte[] ret=new byte[4]; 
     for(int i=0;i<4;i++){ 
      ret[i]=(byte)(value%10); 
      value/=10; 
      ret[i]|=(byte)((value%10)<<4); 
      value/=10; 
     } 
     return ret; 
    } 

Questo è essenzialmente il modo in cui funziona.

  • Se il valore è minore di 0 o maggiore di 99999999, il valore non si adatta a quattro byte. Più formalmente, se il valore è inferiore a 0 o è 10^(n * 2) o superiore, dove n è il numero di byte, il valore non si adatta a n byte.
  • Per ogni byte:
    • Impostare quel byte sul resto del valore diviso per 10 sul byte. (Questo metterà l'ultima cifra nel nibble basso [mezzo byte] del byte corrente.)
    • dividere il valore di 10.
    • Aggiungere 16 volte il resto del valore-divisa-by-10 alla byte. (. Questo metterà l'ormai ultima cifra nel nibble alto del byte corrente)
    • dividere il valore per 10.

(Uno ottimizzazione è quello di impostare ogni byte a 0 in anticipo - che viene implicitamente eseguito da .NET quando assegna un nuovo array e interrompe l'iterazione quando il valore raggiunge 0. Quest'ultima ottimizzazione non viene eseguita nel codice sopra, per semplicità. Inoltre, se disponibile, alcuni compilatori o assemblatori offrono un divide/remainder routine che consente di recuperare il quoziente e il resto in un passo divisione, un'ottimizzazione che di solito non è necessaria.)

+0

funziona favoloso :) – Kingpin

+0

Sei in grado di dirmi cosa sta succedendo qui passo dopo passo? Grazie. – Anonymous

+0

@Anonimo: ho aggiunto una spiegazione. –

1

forse una semplice funzione di analisi contenente questo ciclo

i=0; 
while (id>0) 
{ 
    twodigits=id%100; //need 2 digits per byte 
    arr[i]=twodigits%10 + twodigits/10*16; //first digit on first 4 bits second digit shifted with 4 bits 
    id/=100; 

    i++; 
} 
1

stessa versione come Peter O. ma in VB.NET

Public Shared Function ToBcd(ByVal pValue As Integer) As Byte() 
    If pValue < 0 OrElse pValue > 99999999 Then Throw New ArgumentOutOfRangeException("value") 

    Dim ret As Byte() = New Byte(3) {} 'All bytes are init with 0's 

    For i As Integer = 0 To 3 
     ret(i) = CByte(pValue Mod 10) 
     pValue = Math.Floor(pValue/10.0) 
     ret(i) = ret(i) Or CByte((pValue Mod 10) << 4) 
     pValue = Math.Floor(pValue/10.0) 
     If pValue = 0 Then Exit For 
    Next 

    Return ret 
End Function 

Il trucco è quello di essere consapevole del fatto che semplicemente utilizzando pValue/= 10 sarà arrotondare il valore quindi se per esempio l'argomento è "16", il primo parte del byte sarà corretta, ma il risultato della divisione sarà 2 (dato che 1.6 sarà arrotondato per eccesso). Pertanto utilizzo il metodo Math.Floor.

Problemi correlati