Panowie, wracając do dyskusji, udało mi się zrobić pewne próby z Atmega8 i wyszło na to że operacje których chciałem dokonać działają zaimplementowane jako:
Kopiuj
uint32_t x;
x = 31250UL * (tx - toff);
x /= (tref - toff);
uint16_t wynik = (uint16_t)(x >> 16);
Wyniki są prawidłowe bez żadnych błędów - mi bowiem zależy tylko na części całkowitej ale wynik nie może w części całkowitej zawierać żadnych błędów, ten sposób obliczenia wydaje się być poprawny i działa - testowałem to.
Z drugiej strony zrobiłem także próby na float:
Kopiuj
float y;
y = 31250.0 * (tx - toff);
y /= (tref - toff);
uint16_t wynik = (uint16_t)y;
Wynik również okazał się poprawny.
Porównałem zajętość programu i wyszło na to że kod pierwszy zajmuje 1172 bajty, kod drugi zajmuje 4614 bajtów (w obydwu przypadkach optymalizator był ustawiony na optymalizacje pod kątem rozmiaru kodu). Dodatkowo informuję że po wycięciu obliczeń i rzutowania na wynik kod bazowy zawiera 826 bajtów, zatem można chyba przyjąć że :
- rozmiar kodu obliczeniowego dla operacji stałoprzecinkowych i rzutowania to 1172 - 826 = 346 bajtów
- rozmiar kodu obliczeniowego dla operacji zmiennoprzecinkowych i rzutowania to 4614 - 826 = 3788 bajtów
Dodatkowo zmierzyłem ile się to impulsów zegarowych wykonuje i wyszło że:
- w przypadku pierwszym procesor potrzebował 691 taktów
- w przypadku drugim 4290 taktów
Pomiarów dokonałem przy zastosowaniu timera1 który został wyzerowany bezpośrednio przez dokonaniem obliczeń i którego stan został zapamiętany tuż po zrzutowaniu na zmienną wynik zatem chyba też można tym pomiarom ufać.
Wniosek: w takim przypadku jak moje potrzeby czyli w celu określenia wyniku wyrażenia:
wynik = 31250 * (y - x) / (z - x)
najlepiej będzie zastosować sposób zaprezentowany przeze mnie w jednym z poprzednich postów, czyli sposób oparty o tym stałoprzecinkowy uint32_t.
Dzięki wszystkim za cenne sugestie. Mam jednak dodatkowe pytanie do Szanownych kolegów.
@revcorey napisał że korzystając z biblioteki <stdfix.h> można implementować zmienne typu: volatile sat accum x3, chciałem zapytać co tak naprawdę oznacza sat accum. Podejrzewam że chodzi o typ saturacyjny czyli taki że jak osiągnie max to nawet jak potem mu się coś doda to już nie zmieni tej wartości max. Podobnie z dolnym zakresem. Ale co oznacza accum. Nie mam czasu wszystkiego studiować, zlitujcie się. Poza tym jak taki typ może w ogóle być implementowany jeśli przecież taka "saturacja" wymagałaby jakieś "if - ologii" (inaczej : jak to napisać żeby taki typ powstał, dajcie jakiś kod please).