2011-08-18 15 views
5

Chcę przekonwertować int na tablicę bajtów [4] za pomocą BCD.Konwertowanie tablic bajtów Int na BCD

Ten int będzie pochodzić z identyfikatora urządzenia i jego potrzebnego do komunikowania się z urządzeniem przez port szeregowy.

Czy jest jakaś gotowa funkcja, która to robi, czy możesz dać mi prosty sposób na zrobienie tego?

przykład:

int id= 29068082 

będzie Wydajność:

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

Zakładam, że masz na myśli ', 0x29}'? –

+0

Nie znam żadnej obsługi BCD w bibliotece, najlepszym rozwiązaniem jest niestandardowa funkcja używająca ToString jako pośrednika. –

+0

Tak, to ma być 0x29 Przepraszam .. – Kingpin

Odpowiedz

7

stosowania tej metody.

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

Zasadniczo to działa.

  • Jeśli wartość jest mniejsza niż 0 lub większa niż 99999999, wartość nie mieści się w czterech bajtach. Bardziej formalnie, jeśli wartość jest mniejsza niż 0 lub wynosi 10^(n * 2) lub większa, gdzie n jest liczbą bajtów, wartość nie mieści się w n bajtach.
  • Dla każdego bajtu:
    • Ustaw bajt na pozostałą wartość - podzieloną przez 10 na bajt. (Spowoduje to umieszczenie ostatniej cyfry niskiego "półbajt" bieżącego bajtu).
    • Podziel wartość przez 10.
    • Dodaj 16 razy pozostałą wartość podzieloną przez 10 na bajt. (. Będzie to teraz już ostatnią cyfrę w wysokiej skubać bieżącego bajt)
    • Podzielić wartość o 10.

(Jeden optymalizacji jest ustawić każdy bajt 0 wcześniej - który jest niejawnie wykonywany przez .NET, gdy przydziela nową tablicę - i zatrzymać iterację, gdy wartość osiągnie 0. Ta ostatnia optymalizacja nie jest wykonywana w powyższym kodzie, dla uproszczenia.Ale, jeśli to możliwe, niektóre kompilatory lub asemblery oferują procedura dzielenia/uzupełniania, która umożliwia pobranie ilorazu i reszty w jednym kroku podziału, optymalizacji, która zazwyczaj nie jest konieczna.)

+0

działa świetnie :) – Kingpin

+0

Czy możesz mi powiedzieć, co się tutaj dzieje krok po kroku? Dzięki. – Anonymous

+0

@Anonymous: Dodałem wyjaśnienie. –

1

może prosta funkcja analizy składniowej zawierający tę pętlę

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

samej wersji jak Peter O. ale w 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 

Sztuką jest, aby mieć świadomość, że po prostu za pomocą p-wartość/= 10 będzie zaokrąglić wartość tak, jeśli na przykład argument jest „16”, pierwszy część bajtu będzie poprawna, ale wynikiem podziału będzie 2 (jako 1,6 zostanie zaokrąglone w górę). Dlatego używam metody Math.Floor.

Powiązane problemy