2011-08-26 22 views
15

muszę konwertować wartości (podwójny/pływak w C#) do bajtów i potrzebuje pomocy ..

// Datatype długo 4byte -99999999,99 do 99999999,99
// Datatype długo 4byte -99999999,9 do 99999999,9
// Datatype krótki 2byte -999,99 do 999,99
// Datatype krótki 2byte -999.9 do 999,9

w moim " świat w domu "po prostu napisałbym go i ASCII.GetBytes().

Ale teraz, w tym świecie, musimy zrobić mniejszą przestrzeń.
Rzeczywiście "-99999999,99" zajmuje 12 bajtów zamiast 4! jeśli jest to "długi" typ danych.Konwersja typu danych 'długi' do tablicy bajtowej

[EDIT]
Z powodu jakiejś pomocy i odpowiedzieć na niektóre wyniki załączam tu

long lng = -9999999999L; 
byte[] test = Encoding.ASCII.GetBytes(lng.ToString()); // 11 byte 
byte[] test2 = BitConverter.GetBytes(lng);    // 8 byte 
byte[] mybyt = BitConverter.GetBytes(lng);    // 8 byte 
byte[] bA = BitConverter.GetBytes(lng);     // 8 byte 

Nadal musiał być jeden szczegół w lewo, aby dowiedzieć się. Lng-variabel ma 8 bajtów, nawet jeśli zawiera niższe wartości, tj. 99951 (nie będę zawierał próbki ToString()).

Jeśli wartość jest jeszcze "krótsza", co oznacza -999,99 - 999,99, to zajmie tylko 2 bajty.
[END EDIT]

+0

Wiesz, że długie i krótkie są typu integralnego, więc nie ma miejsc dziesiętnych, prawda? A to, że długie jest 8 bajtów, a nie 4! To jest "int". – xanatos

+1

Jestem zaskoczony, ile odpowiedzi istnieje, gdy pytanie nie ma sensu. Co on ma i co on próbuje zdobyć? –

+0

@xanatos Twój punkt wart jest wspomnienia. Wartości są początkowo zmienne (ale to kolejne pytanie). – Independent

Odpowiedz

5

Pamiętaj, że w 2 bajtach możesz mieć tylko 4 pełne cyfry + znak, a w 4 bajtach możesz mieć tylko 9 cyfr + znak, więc musiałem odpowiednio skalować twoje wymagania wstępne.

public static byte[] SerializeLong2Dec(double value) 
{ 
    value *= 100; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -999999999.0 || value > 999999999.0) 
    { 
     throw new ArgumentOutOfRangeException(); 
    } 

    int value2 = (int)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeLong2Dec(byte[] value) 
{ 
    int value2 = BitConverter.ToInt32(value, 0); 
    return (double)value2/100.0; 
} 

public static byte[] SerializeLong1Dec(double value) { 
    value *= 10; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -999999999.0 || value > 999999999.0) { 
     throw new ArgumentOutOfRangeException(); 
    } 

    int value2 = (int)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeLong1Dec(byte[] value) { 
    int value2 = BitConverter.ToInt32(value, 0); 
    return (double)value2/10.0; 
} 

public static byte[] SerializeShort2Dec(double value) { 
    value *= 100; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -9999.0 || value > 9999.0) { 
     throw new ArgumentOutOfRangeException(); 
    } 

    short value2 = (short)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeShort2Dec(byte[] value) { 
    short value2 = BitConverter.ToInt16(value, 0); 
    return (double)value2/100.0; 
} 

public static byte[] SerializeShort1Dec(double value) { 
    value *= 10; 
    value = Math.Round(value, MidpointRounding.AwayFromZero); 

    if (value < -9999.0 || value > 9999.0) { 
     throw new ArgumentOutOfRangeException(); 
    } 

    short value2 = (short)value; 

    return BitConverter.GetBytes(value2); 
} 

public static double DeserializeShort1Dec(byte[] value) { 
    short value2 = BitConverter.ToInt16(value, 0); 
    return (double)value2/10.0; 
} 

Tak, że to jasne, zakres a (podpisany) krótki (16 bitów) jest -32768 do 32767. więc jest to całkiem jasne, że masz tylko 4 pełne cyfry plus mały element (0-3) , zakres (podpisanego) int (32 bity) wynosi -2,147,483,648 do 2 147 483 647, więc jest całkiem jasne, że masz tylko 9 pełnych cyfr plus kawałek (0-2). Idąc do (podpisanej) długiej (64-bitowej) masz -2222372 036 854 775 808 do 9 223 372 036 854 775 807, czyli 18 cyfr plus (duży) kawałek. Używanie punktów zmiennoprzecinkowych powoduje utratę dokładności. Pływak (32 bity) ma dokładność około 7 cyfr, a podwójny (64 bity) dokładność około 15-16 cyfr.

15

Czy można sprawdzić BitConverter

long lng =-9999999999L; 
byte[] mybyt = BitConverter.GetBytes(lng); 

nadzieją jest to, czego szukasz

+0

Należy pamiętać, że wynik zależy od endianiczności urządzenia. – mpartel

5

spróbować zrobić to w ten sposób:

long l = 4554334; 

byte[] bA = BitConverter.GetBytes(l); 
1
long longValue = 9999999999L; 

     Console.WriteLine("Long value: " + longValue.ToString()); 

     bytes = BitConverter.GetBytes(longValue); 

     Console.WriteLine("Byte array value:"); 

     Console.WriteLine(BitConverter.ToString(bytes)); 
1

Jak wskazano w innych odpowiedziach, można użyć BitConverter, aby uzyskać reprezentację bajtów typów pierwotnych.

Mówiłeś, że w obecnym świecie, który zamieszkujemy, jest ciężar na reprezentowanie tych wartości jako zwięźle jak to możliwe, w takim przypadku należy wziąć pod uwagę variable length encoding (mimo że dokument może być nieco abstrakcyjny). Jeśli zdecydujesz, że to podejście dotyczy twojej sprawy, sugerowałbym przeanalizowanie, w jaki sposób projekt Protocol Buffersrepresents scalar types jest zakodowany za pomocą kodowania o zmiennej długości, co daje krótszy wynik, jeśli zbiór danych faworyzuje mniejsze wartości bezwzględne. (Projekt jest open source pod New BSD license, więc będziesz mógł nauczyć się techniki zastosowanej od source repository lub nawet użyć źródła w swoim własnym projekcie.)

Powiązane problemy