Używam Kinetis Design Studio. MCU: Arm Cortex-M4. Dokładnie jest to MK22FN512VLH12. Definiuję zmienną globalną : double a; . W przerwaniu zmienna jest inkrementowana: a=a+Byle_Co; Program działa poprawnie, ale do pewnego momentu czasowego. W pewnym momencie idzie "w maliny". Sekwencja:
a=a+Byle_Co; if(a>Max)a=0;
rozwiązuje problem. Ile maksymalnie mogę ustawić Max? Za cholerę nie mogę się doszukać maksymalnej wartości zmiennej typu "double" dla mojego MCU. Eksperymentalnie ustawiłem Max=1e6. Program nie idzie w maliny. Jakie może być największe Max?
Double jest z definicji zmiennoprzecinkowe z określoną dokładnością mantysy a dokładna definicja jest zależna m.im. od języka i kompilatora i może być różna Np .w c++ jest zdefiniowana tak:
formatting link
czyli zgodnie z "IEEE-754 binary64 format" co daje jako max jakieś
1.79769e+308
Nie sądzę aby to było problemem. Prędzej ilość miejsc znaczących mantysy bo jeśli Byle_Co jest stałe to po określonej ilości iteracji 'a' przestanie nam się zwiększać.
I jeszcze wielokrotne inkrementowanie liczb zmiennoprzecinkowych nie jest dobrym pomysłem bo błąd zaokrągleń będzie nam narastał i przy odpowiednio dużych iteracjach błąd może być większy niż Byle_Co.
I na koniec konstrukcja
jest zupełnie bez sensu. Bo skoro z definicji 'a' nie może być większe niż Max to cały ten if nie zadziała nigdy prawidłowo.
Proponuję najpierw poczytać podstawy matematyki binarnej i jej ograniczenia.
Nie znam problemu ale zamiast double w przypadku inkrementacji zazwyczaj lepiej użyć zmiennej stałoprzecinkowej.
Ale dlaczego zakladasz że Twórca nie wie co pisze? To chyba jasne że autor zrobił skrót myślowy czyli " Max" to wartość graniczna lokalna (na potrzeby algorytmu) a nie max możliwej (absolutna) dla a.
niedziela, 26 lutego 2023 o 22:01:39 UTC+1 Marek napisał(a):
Hmm, a odpowiedź ma być "tyle samo"? Czy jakaś nieskończoność? W sumie też nie wiem ile to będzie MAX_DOUBLE+1. Trzeba w IEEE-854 sprawdzić.
Hmm, a czy w C można: double d=9; d++; ?
A nie skomentujecie pomysłu robienia sobie licznika z double? I założenia, że "zmiennoprzecinkowa"nkażdą wartość przyjmie? W Bajtku był taki cykl "programować może każdy". Może i prawda, ale "zaprogramować" już niekoniecznie...
Problemem jest , że double jest zmiennoprzecinkowe i jak każdy typ posiada swoją rozdzielczość.
W przypadku a=a+Byle_co; w pewnym momencie osiągnie wartość stacjonarną i nie będzie się już zwiększać bo Byle_Co będzie poniżej błędu pojedynczego bitu dla formatu double ( no chyba że się przekręci ).
Taki przykład:
Czy double i =
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0 da się zwiększać o
0,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 ? Nie. Z tego samego powodu z którego int64_t nie da się zwiększać o 0,1.
Jeżeli chcesz żeby to działało to np :
int64_t a = a + Byle_co; gdzie Byle_co >= 1 żeby miało sens.
double b = (double) a * CONST_VALUE;
Poza tym używanie double w przerwaniu to niekoniecznie dobry pomysł , ale to już inna historia.
Jeżeli mijam się z prawdą lub jak to się kiedyś mówiło - kłamię , proszę o korektę.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.