Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zapis liczb binarnie - nietypowa konwersja integera na char

Ostatnio zmodyfikowano 2016-03-20 12:02
Autor Wiadomość
inomushis
Temat założony przez niniejszego użytkownika
Zapis liczb binarnie - nietypowa konwersja integera na char
» 2016-03-19 18:58:11
Cześć!

Mam do zapisania dużą ilość liczb z zakresu 0 - 99 w pamięci EEPROM pewnego urządzenia.
Aby zaoszczędzić miejsce, którego jest aż 16KB chciałbym zapisać te liczby nie w postaci ASCII, ale w postaci szesnastkowej.
Tzn, zamiast liczby 55 chcę zapisać 0x55. Zamiast 94 - 0x94, zamiast 3 - 0x03.
Dzięki temu 55 zajmie 1 bajt (0x55) zamiast dwóch bajtów( znaki ASCII 5 5 => 0x35 0x35 ).

Takie rozwiązanie pozwoliłoby mi zaoszczędzić 50% pamięci. Pozostaje tylko pytanie - jak przekonwertować inta na postać szesnastkową jakiej oczekuję? Znalazłem milion poradników o zamianie liczy 55 na postać 0x37, czyli zwykła zamiana systemu liczbowego, ale ja chciałbym mieć 0x55. Da radę zrobić to jakoś inaczej, niż ręczne stworzenie tablicy charów, która miałaby pod konkretnym indeksem wartość jakiej oczekuje?


Będę wdzięczny za wszystkie sugestie.
Pozdrawiam
P-146229
jankowalski25
» 2016-03-19 19:01:08
C/C++
a; //cyfra dziesiątek
b; //cyfra jedności
( a * 16 ) + b; //Twoja wartość szesnastkowa

Dopisano:
Jak chcesz zaoszczędzić więcej miejsca, to możesz wszystko posklejać, czyli zamienić
{ 2, 3, 5, 83, 64, 98 }
 na
020305836498
 i szesnastkowo wpisać
0x04BA5279D2
.
P-146230
inomushis
Temat założony przez niniejszego użytkownika
» 2016-03-19 19:34:20
C/C++
unsigned char konwersja_toHex( int liczba ) {
    unsigned dziesiatki = liczba / 10;
    unsigned jednosci = liczba -( dziesiatki * 10 );
    return( unsigned char )( dziesiatki * 16 ) + jednosci;
}

unsigned konwersja_toInt( unsigned char znak ) {
    unsigned dziesiatki = znak / 16;
    unsigned jednosci = znak -( dziesiatki * 16 );
    return( unsigned )( dziesiatki * 10 ) + jednosci;
}

int main()
{
    for( unsigned i = 0; i < 100; i++ ) {
        cout << i << " : " << konwersja_toHex( i ) << " : " << konwersja_toInt( konwersja_toHex( i ) ) << endl;
    }
    return 0;
}
Aż mi głupio, że sam na to nie wpadłem, w sumie logiczne :)
Dziękuję!
P-146237
mateczek
» 2016-03-20 09:39:16
Doprecyzowanie tematu.

Właściwie  to chcesz zrobić nazywa się BCD !!!
W kodzie BCD zapamiętuje się cyfrę na czterech bitach. Efektem ubocznym jest to że liczba wyświetlona szesnastkowo wygląda jak by była zapisana znakami
254(BIN) 1 bajt
254(ASCI)3 bajty
254(BCD) 12 bitów - 1,5 bajta

C/C++
unsigned char konwersja_toHex( int liczba ) { // konwersja do BCD. Właściwie konwertując liczbę z bin do BCD nie oszczędzasz pamięci!!!
    //Ale konwertując ze stringa do BCD tak
    unsigned dziesiatki = liczba / 10;
    unsigned jednosci = liczba % 10; //dzielenie modulo
    return( unsigned char )( dziesiatki << 4 ) | jednosci; //<< przesuń o 4 bity. Operacje binarne zamiast arytmetycznych
}
P-146257
mokrowski
» 2016-03-20 12:02:13
Ba ... zwróć uwagę że:
1. Liczba 99 jest zapisana na 7 bitach a nie na 8 :-) Można jeszcze i ten 1 bit wykorzystać. To pozwoli upakować o ~ 12% jeszcze więcej danych.
2. Być może liczby są od siebie zależne (np. różnią się max o X). Wtedy możesz zapisać różnice.
3. Już "poważnej" kompresji nie sugeruję ...
P-146260
« 1 »
  Strona 1 z 1