logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[c] Efektywne formatowanie liczb w C z uzupełnianiem zerami w Atmel Studio

sorex86 08 Sty 2018 22:58 1851 7
REKLAMA
  • #1 16946782
    sorex86
    Poziom 15  
    Witam,

    Mam następujący problem. Na ogół do formatowania liczb używam sprintf. Jest to wygodne i proste. Jednak zajmuje to sporo miejsca. Obecnie w programie używam struktury, w której mam: wydzieloną cześć całkowitą, dziesiętną oraz miejsce na buffor, który będzie wyrzucany na terminal

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Czy znacie jakaś inna funkcję albo sposób aby efektywnie przenieść część całkowitą oraz ułamkową do tablicy znaków o postaci XXXX.YYYY? Zależy mi na tym aby formatowanie zawsze miało 9 znaków, czyli było uzupełniane zerami. Cześć całkowita XXXX musi być uzupełniana do prawej strony, a część dziesiętna do lewej strony. Funkcja atoi zajmuje o wiele mniej pamięci, niż sprint ale nie ma autouzupełnia zerami. Programuje głownie w atmel studio, megi/xmegi.
  • REKLAMA
  • #2 16946928
    JacekCz
    Poziom 42  
    Jak nie znajdziesz, warto to napisać. To sympatyczne "zadanie dla studenta".
    Pętla dla cyfr całkowitych z dzieleniem całkowitoliczbowym /10, kropka, pętla dziesiętnych z modulo. Strzelam: 100-150 bajtów kodu maszynowego AVR.

    Wariant hardkor, spatchowanie albo wykonanie zamiennika sprintf.
    Wymagane opanowanie grupy funkcji (makr) va_args. Fajne doświadczenie programistyczne.
    Robiłem to za czasów DOS-a. Po wyeliminowaniu zmiennego przecinka i long-ów wielkość funkcji XXXXprintf spadła z kilkunastu kB dołączanego kodu do 1800 B

    PS. wyrzucił bym bufor do formatowania poza strukturę. To jest ZUPEŁNIE inna dana.
    PPS. Zachęcał bym do C++ choćby w formie "C z klasami". Które "studio" używasz? V.4 czy v.7 ?
  • REKLAMA
  • #3 16947227
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #4 16947306
    rajszym
    Poziom 21  
    R-MIK napisał:
    Robiłem to dla int i long ale najprostsze rozwiązania (dzielienie i modulo) generują dłuższy kod niz sprintf.

    No aż sprawdziłem.
    Byle jak napisany zamiennik sprintf daje oszczędność kilkuset bajtów.
  • #5 16947323
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #6 16947380
    rajszym
    Poziom 21  
    R-MIK napisał:
    Dla long ulong, int, uint uwzględniając formatowanie?

    Dokładnie tak.
    Formatowanie oczywiście nieco ograniczone: wyrównanie + uzupełnianie zerami.
  • #7 16951027
    sorex86
    Poziom 15  
    JacekCz napisał:

    PPS. Zachęcał bym do C++ choćby w formie "C z klasami". Które "studio" używasz? V.4 czy v.7 ?


    avr studio 7, gcc. Hm,. dużo ostatnio siedzę w C++, głownie aplikacje pod windowsa (builder, c#, czasem python). Tylko tam 1kb w prawo, w lewo to żaden problem. Xmegi to inny świat chociaż gramatyka podobna. Nie znam "myków" dla uP. Te "myki" to raczej braki w mojej edukacji ;p Dopiero teraz biorę się za operatory bitowe i tego typu sprawy. Zaglądam coraz głębiej pod maskę. Prędzej czy później musiałem dojść do momentu aby porzucić myślenie programowania wysokopoziomowego. Pora iść w stronę myślenia maszynowego, inaczej nigdy nie będzie się pisać optymalnego kodu, optymalnego z rozsądkiem oczywiście, bez sztuki dla sztuki :)

    JacekCz napisał:

    Pętla dla cyfr całkowitych z dzieleniem całkowitoliczbowym /10, kropka, pętla dziesiętnych z modulo. Strzelam: 100-150 bajtów kodu maszynowego AVR.


    Możesz to rozwinąć? Prosty przykładzik, bez kodu aby zrozumiał o co w tym chodzi. Chodzi mi o to aby mieć jak najbardziej uniwersalny kod, bez ifów/elsów typu <10, <100.

    rajszym napisał:
    R-MIK napisał:
    Robiłem to dla int i long ale najprostsze rozwiązania (dzielienie i modulo) generują dłuższy kod niz sprintf.

    No aż sprawdziłem.
    Byle jak napisany zamiennik sprintf daje oszczędność kilkuset bajtów.


    Prawda. itoa + najgorszy algorytm świata zabiera mniej miejsca niż sprintf.
  • #8 16951218
    tmf
    VIP Zasłużony dla elektroda
    sorex86 napisał:
    Prawda. itoa + najgorszy algorytm świata zabiera mniej miejsca niż sprintf.


    Weź tylko pod uwagę, że sprintf zabiera miejsce raz i daje ci uniwersalne możliwości formatowania łańcuchów. Takie samoróbki są dobre o ile masz bardzo ściśle określone potrzeby - czyli jeden typ zmiennej zawsze formatujesz w taki sam, lub bardzo podobny sposób i musi to być zoptymalizowane. W większej aplikacji zazwyczaj nie ma sensu taka optymalizacja. Kolejna sprawa - jeśli cie te kilkaset dodatkowych bajtów boli, to znaczy, że źle wybrałeś mikrokontroler. Wybierz taki, który ma więcej FLASH i zapomnij o kombinacjach. Przynajmniej na początku zabawy z mikrokontrolerami szkoda czasu na wyważanie otwartych drzwi. A jeśli już musisz, to użyj uitoa i itoa (zauważ, że część dziesiętna nie może być ujemna), oraz funkcji z nagłówka string.h, do manipulacji łańcuchami. Zapewne nic lub niewiele w stosunku do sprintf zaoszczędzisz, ale będzie to nauczka na przyszłość. No i możesz używać fixed point math zamiast robić wygibasy z osobno trzymaną częścią całkowitą i ułamkową. No chyba, że 16 bitowa precyzja części ułamkowej jest ci potrzebna.
REKLAMA