Zealota Listopad 23, 2019 Udostępnij Listopad 23, 2019 18 minut temu, ethanak napisał: 10 godzin temu, Zealota napisał: Gdzie to niby pisałem o zmiennej RPM? A tutaj: Hmm. Przecież jawne rzutowanie zmiennej typu int na float, nie zmienia tej zmiennej. Ona nadal jest typu int, a jedynie - jakby to powiedzieć - "kontener" na liczby się powiększa, żeby zaspokoić zmienną f i wynik jest zgodny z oczekiwaniem, tzn. z deklaracją zmiennej f, bez obcinania zakresu do int. Natomiast zmiana z 60 na 60.0 właśnie dokonuje tej zmiany na liczbie, co oczywiście poprawnie służy zadaniu, ale wprost liczbę całkowitą zamienia na float, niepotrzebnie zaburzając logiczną deklarację zakresów zmiennych, ale o tym już pisałem wyżej. Zatem moją intencją w powyższym zapisie było to, żeby właśnie rozszerzyć "ten kontener", a nie żeby "nadać cechy" zmiennej RPM. Oczywiście wyszła tu pewna niewiedza, bo przy okazji sprawdziłem z kompilatorem w ręce 3 zapisy dla avr-gcc bez optymalizacji. float f = RPM*2/60.0; // wariant jeden float f = (float)(RPM*2)/60; // wariant dwa float f = (float)RPM*2/60; // wariant 3 Okazuje się, że pomimo poprawnej wartości dla każdego z nich jednak niektóre dadzą więcej instrukcji , a niektóre mniej. No to zagadka. Które dają mniej, a które więcej? Bez kompilatora 🙂 Przyznaję się bez bicia, że ja nie wiedziałem, ale orłem nie jestem. Podsumowując wątek moją główna intencją było to, że im bardziej wzór w kodzie przypomina ten wyliczony na kartce tym lepiej, a jawne rzutowanie jest w tym przypadku lepszym, czytelniejszym rozwiązaniem, bo zakresy liczb odpowiadają ich rzeczywistym zakresom. Jak widać to są pewne drobne niuanse, być może mało ważne w praktyce, ale raczej "rozkmina" na tym poziomie to istotna nauka programowania. Nie sądzicie? Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Listopad 23, 2019 Udostępnij Listopad 23, 2019 Wszystko niby ok - ale tylko niby. Dzielisz liczbę impulsów przez czas pomiaru - a ten wcale nie musi być liczbą całkowitą. Wyobraź sobie dokładniejszą wersję programu, gdzie ów czas jest różnicą między pierwszym i ostatnim pomiarem (właściwie następnym po ostatnim) Można się bawić w milisekundy - ale tu już niedaleko do przekroczenia zakresu int. A dzienie floatów jest w AVR-ach szybsze niż dzielenie long int... Dlatego właśnie czas pomiaru jest wartością zmiennoprzecinkową (np. 59.75). O to mi chodziło. Zauważ, że Ty też używasz niejawnego rzutowania - bo przecież aby wykonać dzielenie kompilator musi zmienić stałą 60 (int) na 60.0 (float). Owszem - optymalizator zrobi z tego (float) RPM/30.0, ale chyba nie o to chodzi w tym całym rzutowaniu? Cytuj Link do komentarza Share on other sites More sharing options...
Zealota Listopad 23, 2019 Udostępnij Listopad 23, 2019 1 godzinę temu, ethanak napisał: Wszystko niby ok - ale tylko niby. Dzielisz liczbę impulsów przez czas pomiaru 1 godzinę temu, ethanak napisał: Wyobraź sobie dokładniejszą wersję programu, No właśnie nie chcę tu sobie na razie wyobrażać bardziej uniwersalnych, rozszerzonych przypadków, bo jeśli do nich by doszło to należałoby cały koncept zapisu przemyśleć i pewnie sposób z przecinkiem byłby bardziej na miejscu, a może jeszcze coś innego by należało użyć. Mnie chodzi tutaj cały czas o ten konkretny przykład jaki podał autor. Można się tylko domyślać, ale jednak wszystko na to wskazuje, że chodzi mu o rozdzielczość czasu na poziomie załóżmy sekund (mogą być również minuty), nie milisekund czy jeszcze mniej. Z tego powodu tak się upieram (pewnie jednak zbyt literalnie) na te części ułamkowe, które nie są ułamkowe. Zresztą samo f to nie wiadomo do czego, czemu tam *2 itd 🙂 Tak czy siak wydaje mi się, że rozumiem tok Twojego rozumowania i raczej na pewno wnioski jakie powstały w wątku będą przydatne. Nie zamykam się całkowicie na formę zapisu z przecinkiem, być może kiedyś zajdzie potrzeba to "się użyje". Cytuj Link do komentarza Share on other sites More sharing options...
Chumanista Listopad 23, 2019 Udostępnij Listopad 23, 2019 9 godzin temu, Zealota napisał: Ona nadal jest typu int, a jedynie - jakby to powiedzieć - "kontener" na liczby się powiększa, żeby zaspokoić zmienną f i wynik jest zgodny z oczekiwaniem, tzn. z deklaracją zmiennej f, bez obcinania zakresu do int. No właśnie nie, liczba zostanie przeniesiona do nowego miejsca w pamięci z konwersją która w niektórych przypadkach może powodować stratę dokładności (jeżeli int ma więcej niż 23 bity); https://stackoverflow.com/questions/7775129/int-to-float-conversion-produces-a-warning 9 godzin temu, Zealota napisał: Okazuje się, że pomimo poprawnej wartości dla każdego z nich jednak niektóre dadzą więcej instrukcji , a niektóre mniej. Obstawiam że wariant 1 i 2 - każdy tak samo będzie miał zmiennoprzecinkowe dzielenie ale tylko 3 będzie miał mnożenie. Sprawdźmy. AVR gcc 9.2.0: O0: 1 - 42, 2 - 42, 3 - 61 O3: 1 - 28, 2 - 28, 3 - 39 1 Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!