Ciekawy problem ze zmienną - Wersja do druku +- Arduino Polska Forum (https://forum.arduinopolska.pl) +-- Dział: Korzystanie z Arduino (https://forum.arduinopolska.pl/dzial-korzystanie-z-arduino) +--- Dział: Instalacja i rozwiązywanie problemów (https://forum.arduinopolska.pl/dzial-instalacja-i-rozwi%C4%85zywanie-problem%C3%B3w) +--- Wątek: Ciekawy problem ze zmienną (/watek-ciekawy-problem-ze-zmienn%C4%85) |
Ciekawy problem ze zmienną - kilof206 - 01-11-2017 Cześć. Napotakłem na ciekawy problem. Czy ktoś go może wytłumaczyć? A jak temu zapobiec? W wyniku uruchomienia poniższego kodu, w monitorze dostajemy dwa wyniki (oba poprawne): 24000; Kod: long z; Jeśli natomiast przypisanie wartości do zmiennej z=48 przeniesiemy w kodzie nieco wyżej, zaraz pod Serial.begin, czyli: Kod: void setup() w monitorze zobaczymy: 24000 23999 Dlaczego druga wartość jest błędna? Zauważyłem również, że taka konstrukcja da poprawne wyniki: Kod: void setup() jak i również zadeklarowanie z wewnątrz setup() również poprawnie wyświetli wartości, czyli: Kod: void setup() Testy przeprowadzałem na Arduino UNO w IDE 1.8.5. Pozdrawiam, Marcin RE: Ciekawy problem ze zmienną - Robson Kerman - 01-11-2017 W funkcji func() następuje konwersja typu int na float, a funkcja zwraca unsigned long. Dzielenie c/(float)b daje wynik przybliżony, coś w postaci 1.9999999, więc wynik potęgowania to 3.9999997, a 6000*3.9999997=23999.9982. Konwersja do long zwraca część całkowitą wyniku, czyli 23999. A dla czego tak się dzieje, że w zależności gdzie zadeklarujesz, lub gdzie przypiszesz zmiennej z wartość, to otrzymujesz różne wyniki? Jest to automatyczne rzutowanie typów zadeklarowanych zmiennych w zależności od tego, co kompilator uzna za stosowne. Kompilator konwertuje typy zawsze gdy jest to tylko możliwe i gdy już wie, że będzie dzielenie long przez float, bo użyłeś funkcji func(), to nie będzie rzutował c na float, bo wie że wyniki będą nieprawdziwe. W normalnym kompilatorze powinno wyskoczyć ostrzeżenie, że wyniki będą przybliżone, chociaż pewnie GCC nie popełnił by tego błędu, bo inna jest kolejność kompilacji. |