Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

AVR-GCC (ATmega) obliczenia zmiennoprzecinkowe

voytaschec 28 Lut 2008 16:54 2701 4
  • #1 28 Lut 2008 16:54
    voytaschec
    Poziom 24  

    Witam.
    W prawie całym programie używam zmiennych 8bit (uint8_t), ale w jednym miejscu jestem zmuszony do obliczeń zmiennoprzecinkowych.
    Mam pytanie:
    jak najprościej wykonać obliczenie zmiennoprzecinkowe (z dzieleniem) na liczbach uint8_t, tak aby wynikiem także była liczba uint8_t?

    Gdy wykonam zapis np.:
    uint8_t a;
    a=10*(20/3);

    to w wyniku dostanę liczbę 60 (a powinno być 66). Nie pomaga też coś takiego:
    float a;
    uint8_t b;
    a=10*(20/3);
    b=a;

    wtedy także w wyniku będzie liczba 60.
    Kto wie jak wykonać takie obliczenia?

  • Pomocny post
    #2 28 Lut 2008 17:06
    markosik20
    Poziom 33  

    voytaschec napisał:

    jak najprościej wykonać obliczenie zmiennoprzecinkowe (z dzieleniem) na liczbach uint8_t, tak aby wynikiem także była liczba uint8_t?


    Wcale nie musisz wykonywać dzielenia na zmiennoprzecinkowych :wink:

    wystarczy że zrobisz np: tak:

    Code:
    uint8_t a;
    
    uint16_t b;
    b=(20*10)/3;
    b*=10;
    a = b/10;


    Zasada jest taka żeby "przesunąć" przecinek z ilorazu w prawo aby uzyskać większą dokładność.

  • #3 28 Lut 2008 17:29
    voytaschec
    Poziom 24  

    Niestety takie coś także nie pomaga :(
    W tym przykładzie, który napisałem nawias nie jest bez znaczenia. Chodziło mi o to, żeby pokazać, że w pewnym momencie (dokładnie przy 20/3) wychodzi liczba zmiennoprzecinkowa (6,66), która po przemnożeniu przez 10 i konwersji na liczbę całkowitą powinna wynosić 66, a tak niestety się nie dzieje. Cały czas otrzymuję 60.
    Ten przykład, co podałem to jest "wyssany z palca", w rzeczywistości mam dużo bardziej skomplikowany wzór z bardzo dużą ilością zmiennych (wszystkie uint8_t).


    Zaznaczę jeszcze, że nie zależy mi na oszczędności miejsca, robię to na ATmega128 i jeszcze bardzo dużo zasobów mi zostało.

  • Pomocny post
    #4 28 Lut 2008 18:18
    markosik20
    Poziom 33  

    Ale takie coś już działa :wink:.

    Code:
    float a; 
    
    uint8_t b;
    a = 20;
    a/=3;
    a*=10;
    b = a;


    Chodzi generalnie o jawne rzutowanie typów.

  • #5 28 Lut 2008 18:45
    voytaschec
    Poziom 24  

    Wielkie dzięki @markosik20.

    Tak szczerze to ten pierwszy twój przykład też zadziałał (po zwiększeniu do liczb uint32_t i mnożeniu przez 1000 a następnie dzieleniu). Drugi też działa i chyba z niego skorzystam (ze względu na dokładność).

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME