ATNEL tech-forum https://forum.atnel.pl/ |
|
Typy zmiennych-pytanie o poprawność w programie https://forum.atnel.pl/topic22154.html |
Strona 1 z 1 |
Autor: | Robert_1967 [ 9 kwi 2019, o 11:59 ] |
Tytuł: | Typy zmiennych-pytanie o poprawność w programie |
Witam. Mam prośbę o opinię w kwestii poprawności typów zmiennych. Ostatnio wpadło mi w ręce pcb generatora dds na ad9850-popularny "chińczyk". Postanowiłem go ożywić. Udało mi się to i generatorek działa. Próbowałem różnych metod wysyłania danych po spi od tych "kodo żernych" po bardziej wyszukane i jak twierdzą inni, lepsze. Robiłem wcześniej próby z ad9952 również z podobnym skutkiem. Przykłady zaczerpnąłem z internetu oczywiście. Ostatnie próby robiłem z użyciem uni. Działa, ale nie do końca jestem pewny poprawności kodu (zakresu zmiennych). Wygląda to mniej więcej tak: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Dalej wysyłam obliczoną nastawę do dds-a w sekwencji 4 bajtów + potem jeszcze bajt konfiguracyjny. język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Nastawa jest liczona następująco: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. I teraz po przemyśleniu wychodzi mi tak: Liczba 4294967296 nie mieści się w unsignet long 32 bity (końcówka 6). Po przemnożeniu 4294967296 * freq(np. 40000000) = 171798691840000000 ---> bardzo duża liczba. Po podzieleniu wyniku przez 125000000 otrzymujemy 1374389534,72 Zmienna FTW jest również 32 (ale long co prawda). Proszę o ocenę, jak to się ma do "całości". Czy jednak należałoby napisać inaczej. Pozdrawiam. |
Autor: | Robert_1967 [ 9 kwi 2019, o 13:27 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Dzięki zubik Tak na szybko odpisuje, ponieważ muszę odejść od kompa. Bardzo ciekawie to ująłeś. Muszę przemyśleć na spokojnie. Jedyne, co mi się nasuwa na początku, to czy jest to poprawne rozwiązanie w tej konkretnej sytuacji. Na razie dzięki za chęć pomocy. Pozdrawiam. |
Autor: | Lex_ [ 9 kwi 2019, o 21:22 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Podłączę się bo przypadkowym trafem też zakupiłem moduł AD9850 i chcę wykonać na nim generator / BFO. Obliczenia kolegi @zubik wyglądają dobrze. Ja sam brałem pod uwagę konwersję liczby do tablicy ale póki co wykonam testy dla zwykłego obliczania. Pozdrawiam. |
Autor: | andrews [ 10 kwi 2019, o 08:48 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Robert_1967 napisał(a): Rozumiem, że ten wzór ma obliczyć wartość przyrostu fazy, jaką trzeba wprowadzić do AD9850 w celu uzyskania częstotliwości wyjściowej o wartości zmiennej frequency. zubik napisał(a): Zawsze możesz mnożniki zmniejszyć do minimalnego rozmiaru np: 4294967296 * freq(np. 40) = 17 179 869 1840 a potem to podzielić przez 125 wynik będzie ten sam ale mikrokontroler szybciej uwinie się z obliczeniami. A jeśli przykładowo będziesz chciał uzyskać częstotliwość np. 6 451 200? Okazuje się, że "mnożnik" nie może być zawsze taki sam, trzeba by go ustalać indywidualnie dla każdej wartości częstotliwości. Poza tym "mnożnik" równy 100 niewiele zmieni, jeśli chodzi o rozmiar zmiennej. Pomysł ogólnie dobry, ale można go raczej zastosować w sytuacji, kiedy możemy znaleźć wspólny dzielnik dla stałych zastosowanych w programie. Myślę, że w tym przypadku, aby uzyskać maksymalną rozdzielczość/dokładność częstotliwości oferowaną przez układ, nie da się uniknąć obliczeń na liczbach 64-bitowych. Oczywiście zmienne mogą pozostać 32-bitowe (tak czy inaczej, wynik przecież musi się zmieścić w 32 bitach), jednak na pewnym etapie obliczeń należałoby je rzutować na zmienne 64-bitowe. Przykładowo takie obliczenia: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. powinny dać prawidłowy wynik (pod warunkiem oczywiście, że frequency < CLKIN). Czas wykonania obliczeń to ok. 1300 taktów zegara, co przy taktowaniu 16MHz daje niecałe 82us. Rewelacyjnie nie jest, ale w przypadku generowania częstotliwości stałych takie opóźnienie to nie jest chyba duży problem. Gdyby ktoś chciał użyć modulacji częstotliwości dla przebiegu o kształcie znanym w czasie kompilacji, można użyć tablicy z predefiniowanymi wartościami przyrostu fazy zapisanej np. w pamięci FLASH (odczyt gotowych wartości z pamięci będzie na pewno dużo szybszy niż ich obliczanie). Problemem może być modulacja szybkozmiennym sygnałem zewnętrznym, którego wartości chwilowe są odczytywane przez ADC i przyrost fazy musi być obliczany w czasie rzeczywistym na podstawie wyniku pomiaru. |
Autor: | Robert_1967 [ 11 kwi 2019, o 09:00 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Mam prośbę o zweryfikowanie kodu. Postanowiłem wykonać obliczenia na dłuższych liczbach i następnie wysłać nastawę do dds na 32 bitach. Chciałem zastosować jawne rzutowanie. Proszę o opinię, czy słusznie kombinuję, czy raczej komplikuję sobie zagadnienie. Jeśli droga jest słuszna, to czy kod napisałem prawidłowo. Proszę o wyrozumiałość w moich wypocinach . Unia wygląda następująco: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Następnie robię takie rzutowanie na 32 bity w funkcji wysyłania czterech bajtów: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Czy tak jest poprawnie i metoda jest słuszna ???. PS Czy może ktoś wie, jaki popełniam błąd przy wstawianiu kodu SYNTAX C do postu ?. Zawsze na początku mam przesunięcie tekstu i nijak nie mogę tego wyrównać. |
Autor: | andrews [ 11 kwi 2019, o 09:31 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Mam wrażeni, że nie przeczytałeś zbyt dokładnie tego, co napisałem w poprzednim moim poście. Cytuj: Nie musisz zmieniać typu zmiennych. Możesz mieć tak jak miałeś. Użycie przyrostka ULL wymusi na kompilatorze wykonanie obliczeń na liczbach 64-bitowych, po czym wynik zostanie obcięty do 32 bitów i przypisany do Twojej zmiennej. Jeśli już koniecznie chcesz jawnie rzutować, to wystarczy tak: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. To co zrobiłeś nie ma większego sensu. Tak naprawdę rzutujesz 8-bitowe elementy tablicy na zmienne 32-bitowe i próbujesz je wysłać po SPI. Argument Twojej funkcji send_spi() i tak zostanie najprawdopodobniej obcięty do 8 bitów. Nie miałeś żadnych ostrzeżeń podczas kompilacji? |
Autor: | Robert_1967 [ 11 kwi 2019, o 10:07 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Dzięki andrew Dzięki, ze chociaż Ty masz chęć nieraz odpisać. No tak już mam, że nieraz lubię komplikować sobie życie. Ja zawsze czytam i to dokładnie. Problem w tym, że nie zawsze rozumiem. Jako, że poznaję C całkowicie sam, to trudno mi zrozumieć czasem. Mam książki Mirka, czytam w internecie, ale ze zrozumieniem trochę na bakier. Może mam złą metodę, źle się uczę. Ale to mój kłopot i nie będę nikogo zanudzał. Ok wrócę to początku tak, jak było i idę dalej. Muszę dołożyć przyciski (potem enkoder) i napisać funkcje do przestrajania. Step by step, jak to mówią . Pozdrawiam. ------------------------------- Zapomniałem dopisać, że ostrzeżeń nie było. Kompilacja przebiegała prawidłowo i po wgraniu był normalny przebieg na wyjściu DDS-a. Ja sądziłem, że jak wykonam taki zapis język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. to zostanie zmienione tylko FTW.u64 na FTW.u32 a tablica pozostanie u8. No ale to wynika z mojej niewiedzy, ponieważ nie wykorzystywałem jawnego rzutowania do tej pory. No może poza jednym przypadkiem dawno temu i nie mam tego wyuczonego. |
Autor: | andrews [ 11 kwi 2019, o 18:28 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Robert_1967 napisał(a): wrócę to początku tak, jak było i idę dalej Zauważ tylko różnicę między Twoim kodem, a tym co pokazałem, czyli przyrostki ULL. Dzięki temu masz pewność, że obliczenia będą wykonane na typie unsigned long long (czyli w przypadku AVR 64-bitowym).Robert_1967 napisał(a): Ja sądziłem, że jak wykonam taki zapis język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. to zostanie zmienione tylko FTW.u64 na FTW.u32 a tablica pozostanie u8. Spróbuję jak najprościej. W przypadku stworzonej przez Ciebie unii:
FTW.uint64 jest typu uint64_t Analogicznie, kiedy rzutujesz:
(uint32_t)FTW.uint64 następuje konwersja typu z uint64_t do uint32_t, czyli następuje obcięcie czterech najbardziej znaczących bajtów. Zakładając, że Twoja zmienna 64-bitowa jest równa 0000 0000 25AC 56B1 (heksadecymalnie) to po konwersji:
(uint32_t)FTW.uint8[1], czyli uint8_t do uint32_t otrzymasz wartość 0000 0056 (uint32_t)FTW.uint8[2], czyli uint8_t do uint32_t otrzymasz wartość 0000 00AC (uint32_t)FTW.uint8[3], czyli uint8_t do uint32_t otrzymasz wartość 0000 0025 (uint32_t)FTW.uint64, czyli uint64_t do uint32_t otrzymasz wartość 25AC 56B1 Rzutowanie nie oznacza zmiany typu zmiennej w jakimś sensie permanentnym, czy też globalnym. Poprzez rzutowanie programista mówi tylko kompilatorowi:
Pisząc tak:
Robert_1967 napisał(a): Zapomniałem dopisać, że ostrzeżeń nie było. Kompilacja przebiegała prawidłowo i po wgraniu był normalny przebieg na wyjściu DDS-a. To jeszcze nie musi oznaczać, że wszystko jest OK. Nie wszystkie ostrzeżenia są standardowo włączone, a kompilator często skutecznie potrafi sprostować niektóre błędy programisty. No ale jednak nie zawsze sobie poradzi, dlatego dobrze jest jednak precyzyjnie i poprawnie przedstawiać mu swoje oczekiwania. Jeszcze co do jawnego rzutowania - niektórzy traktują je jako panaceum na pozbycie ostrzeżeń kompilatora. Jeśli kompilator wyświetli ostrzeżenia dotyczące typu, to trzeba rzutować jawnie wartość na określony typ i po kłopocie. Taka taktyka sprawdza się niestety tylko wtedy, kiedy przed rzutowaniem programista dobrze przemyśli wszelkie możliwe implikacje takiej decyzji i uzna, że nie doprowadzi ona do jakiejś katastrofy. Rzutowanie może powodować w niektórych przypadkach utratę pewnych informacji (np. obcięcie części ułamkowej w przypadku konwersji float do int), więc trzeba dobrze przemyśleć, jakie to będzie miało skutki i jak one wpłyną na poprawność działania całej aplikacji. Robert_1967 napisał(a): Dzięki, ze chociaż Ty masz chęć nieraz odpisać. Każdy ma jakiegoś bzika... |
Autor: | andrews [ 12 kwi 2019, o 09:44 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Robert_1967 napisał(a): Po pierwsze: Moim zdaniem lepiej jednak jest korzystać z nazw typów, które jasno określają ich szerokość w bitach, czyli:
Po drugie: Nadal masz zmienną 64-bitową w Twojej unii, a w zupełności wystarczy 32-bitowa: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Sprawę wymuszenia obliczeń na liczbach 64-bitowych załatwi przyrostek ULL przy zdefiniowanych stałych. Robert_1967 napisał(a): frequency = 25000000ULL; Zmienna frequency jest typu uint32_t i taka może być, jednak wartości 64-bitowej do niej i tak nie wpiszesz, więc spokojnie możesz tutaj pominąć przyrostek ULL. Robert_1967 napisał(a): Jest to najczęściej spotykana metoda, ale jak pisałem wcześniej, to podobno z użyciem uni ten kod działa najszybciej, a więc uparłem się na niego Wiesz, nie chce mis się teraz tego testować, ale wydaje mi się, że kompilator, po napotkaniu na przesunięcia bitowe podzielne przez 8, przynajmniej wtedy, gdy kompiluje kod dla 8-bitowego mikrokontrolera, nie będzie używał czasochłonnych przesunięć bitowych, tylko odczyta po kolei poszczególne bajty, podobnie jak w przypadku odczytu z tablicy. Jestem tego prawie pewien, choć gwarancji nie dam. Poza tym gdyby ten kod nieco przerobić, to można by go przyspieszyć: język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Gdyby napisać w ten sposób, to nawet jeśli przesunięcia bitowe byłyby wykonywane, działoby się to w trakcie transmisji SPI, a i tak czekasz na jej zakończenie, zarówno tutaj, jak i w kodzie z unią. Nie wiem, z jaką prędkością te dane wysyłasz, ale jest szansa, że w trakcie transmisji przesunięcia zdążyłyby się wykonać. Tutaj dane są bezpośrednio wpisywane do rejestru SPDR, w kodzie z unią wywołujesz funkcję wysyłającą, a każde wywołanie i powrót z funkcji pochłania dodatkowe takty zegara. W kodzie z unią cczekasz na wysłanie danych, a dopiero później odczytujesz dane z tablicy, aby wysłać następny bajt, tutaj następny bajt można przygotować w czasie transmisji. W celu uzyskania odpowiedzi, który kod jest szybszy, należałoby wykonać testy, przeliczyć takty, ale nie za bardo mam na to czas. andrews napisał(a): Robert_1967 napisał(a): Dzięki, ze chociaż Ty masz chęć nieraz odpisać. Każdy ma jakiegoś bzika... Robert_1967 napisał(a): Nie widzę, jak wstawić cytat "Dzięki, ze chociaż Ty masz chęć nieraz odpisać." Poniekąd rozumiem, że to nie jest forum do nauki C od podstaw. Jeśli ktoś chce się uczyć, to niech idzie do szkoły, a nie szuka korepetycji za darmo Nie wiem, czy mnie dobrze zrozumiałeś. Nie miałem zamiaru Cię urazić. Niemniej moim zdaniem forum jest jak najbardziej także dla początkujących. Jednak nauka programowania, tak jak wszystkie nauki ścisłe, wymaga zachowania pewnej kolejności w zdobywaniu wiedzy. Problem z początkującymi często polega na tym, że są niecierpliwi i chcą na skróty osiągnąć wysoki poziom, przez co odpowiedzi na ich pytania muszą być bardzo obszerne, a każda odpowiedź rodzi następne pytania. Nie traktuj tego jako złośliwość, tylko jako dobrą radę, żeby uczyć się z zachowaniem odpowiedniej kolejności, systematycznie, nie za szybko zwiększać stopień trudności swoich projektów i uzbroić się w cierpliwość, a efekty na pewno z czasem przyjdą. Pozdrawiam Andrzej |
Autor: | Zealota [ 12 kwi 2019, o 11:00 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
andrews napisał(a): Zmienna frequency jest typu uint32_t i taka może być, jednak wartości 64-bitowej do niej i tak nie wpiszesz, więc spokojnie możesz tutaj pominąć przyrostek ULL. No nie do końca można pominąć. Trzeba zastosować właściwy, w tym wypadku UL, czyli unsigned long (32 bit, bez znaku). Stosowanie przyrostków UL, ULL jest po to, w mojej opinii, żeby nie musieć jawnie rzutować w każdym miejscu, gdzie powinno być zrobione, bo właściwą interpretację dla preprocesora stanowią właśnie przyrostki. Domyślna promocja do int, dla realnie dużych wartości liczb (z dużym prawdopodobieństwem przekroczenia zakresu, jak w tym przypadku), w momencie zaniedbania rzutowań jest niebezpieczna, zatem należałoby wstawiać te przyrostki przy korzystaniu z #define. Inny sposób, jeśli ktoś jednak chce korzystać z #define to korzystać z konstrukcji: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Powyższe sposoby są równoważne, ale niemniej jednak bardzo istotne. |
Autor: | Robert_1967 [ 12 kwi 2019, o 11:09 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Dziękuję Andrzeju. Jeszcze nie znalazłem metody na cytowanie, ale poszukam. " Nadal masz zmienną 64-bitową w Twojej unii, a w zupełności wystarczy 32-bitowa: " Tutaj moja wina, ponieważ zrobiłem kopiuj-wklej na szybko i nie skasowałem LL. " uint8_t zamiast unsigned char uint64_t zamiast unsigned long long int int16_t zamiast int itd. " Ja zazwyczaj stosuje metodę uint8_t itd... Tutaj akurat na tą chwilę trzymałem się oryginalnej części kodu i nie zmieniałem. I tak co jakiś etap staram się robić jakąś optymalizację, tak że to na razie. Dalej, ja się tak szybko nie obrażam . Tutaj to ja przepraszam. Może źle napisałem. Ja pisałem ogólnie o całym forum, że to w sumie nie miejsce na naukę od podstaw itd... Co do opińii o początkujących, to zgadzam się w całej rozciągłości. Wiem sam po sobie. Jeśli coś się udaje, ale nie do końca rozumiem temat, to idę dalej, a to czego nie wiem, to odkładam "na potem". Ja wiem, że robię kardynalny błąd i to się potem mści tak, jak w tym przypadku. Gdybym na spokojnie przeanalizował temat chociażby rzutowania, nauczył się na 99%, to tego tematu by nie było, a ja byłbym dalej z projektem. Nie mniej jednak myślę, że i tak małe bo małe, ale robię postępy, tylko trochę po łepkach i to źle. Ok. Pisanie i testowanie zacznę od poniedziałku. Teraz inne priorytety (dom). Kończąc dodam, że ktoś inny napisał, że inicjacja i wysłanie freq. do dds-a, to tylko jeden procent projektu i najłatwiejsza część. Pozostałe 99%, to interfejs użytkownika i cala reszta z tym związana. Zobaczę, jak sobie poradzę. Mam czas . Pozdrawiam. Robert. ---------------------Dodano------------------- Tutaj jeszcze pozwolę sobie zacytowć tekst z innego forum. Pisały to osoby, które można by stwierdzić, ze są guru w temacie syntez i ich budowy oraz oprogramowania. Teksty skierowane nie do mnie, tylko dyskusja. " nie jestem ekspertem od GCC-AVR ale zastanawia mnie jakim cudem podczas mnożenia dwóch liczb 4 bajtowych (long int) chcesz zmieścić wynik na 4 bajtach. " oraz " FTW jako ciąg bitów wysyłanych do DDS - wynik obliczeń musi być 32 bitowy... można sobie po drodze liczyć na "dłuższych" liczbach ale na koniec trzeba : - albo liczbę "obciąć" do 32 bitów - albo świadomie wysłać 32 młodsze bity " Pozdrawiam. |
Autor: | Marhef [ 12 kwi 2019, o 13:32 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Robert_1967 napisał(a): Jeszcze nie znalazłem metody na cytowanie, ale poszukam. Z tym akurat mogę pomóc (bo z postawionym problemem nie bardzo )W prawym dolnym rogu każdego posta masz dwa przyciski - cytuj i cytowanie selektywne. Korzystając z nich możesz cytować. Albo możesz też "z palca" - tylko to, co piszę, musisz wpisać w nawiasy kwadratowe []. Rozpoczęcie cytowania to quote="nick", a zakończenie to /quote |
Autor: | Robert_1967 [ 12 kwi 2019, o 14:19 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Dzięki. Co do tematu, to mi pomogłeś, jak i kolega zealota. Tak czy inaczej w różnych przykładach z różnych projektów, które widziałem (wiele na arduino) to przeważnie obliczenia były wykonywane na dłuższych liczbach, a do dds-a wysyłane na 32 bitach. Chciałem jeszcze podejrzeć np. na lcd te liczby, ale coś nie wychodziło. Jeszcze pokombinuje. Pozdrawiam. Co do szybkości wykonywania tych działań to zależało mi dla tego, że jak będzie inpulsator-enkoder, to żeby nadążył przy szybszych pokręceniach. Ja mam taki chyba 250 kroków i nie chciałbym, a żeby gubiło kroki itp...No oczywiście reszta musi być nie blokująca, to wiem. Może trochę trudny temat, ale mi się nie spieszy i wiele z tego wyniosę. Pozdrawiam. |
Autor: | tec-dive [ 12 kwi 2019, o 14:45 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Robert_1967 napisał(a): Chciałem jeszcze podejrzeć np. na lcd te liczby, ale coś nie wychodziło. Trochę zgaduję, ale podejrzyj jakiego typu zmienne obsługuje funkcja do wyświetlania ich na LCD Możliwe, że "przekręca" Ci zakres - to taka podpowiedź |
Autor: | Robert_1967 [ 12 kwi 2019, o 15:25 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Dzięki tec_dive Po niedzieli pokombinuję. Kiedyś napisałem funkcję do wyświetlania długich liczb (z pomocą forum oczywiście) lcd_long(); i wyświetlało prawidłowo długie ciągi liczb, ale być może trochę inny typ i tu mi coś nie działało. Fakt, że zaraz to zostawiłem, ponieważ bardziej byłem skupiony na tym temacie. Wrócę do tego. Dzięki za podpowiedź. Pozdrawiam. |
Autor: | andrews [ 12 kwi 2019, o 18:51 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Robert_1967 napisał(a): Co do opińii o początkujących, to zgadzam się w całej rozciągłości. Wiem sam po sobie. A jak myślisz, skąd ja o tym wiem? Też kiedyś byłem początkujący, choć wcale nie twierdzę, że teraz już wiem wszystko. Może jednak nie będę się już rozpisywał na ten temat, żeby nie zwiększać off-topu. Chciałbym jednak jeszcze odpowiedzieć koledze Zealota. Ogólnie zgadzam się z tym, że stosowanie odpowiednich przyrostków określających typ stałej jest ważny. Jak pewnie zauważyłeś, sam pierwszy w tym wątku zacząłem o tym pisać. Chciałbym jednak, żebyś zauważył także fakt, że moja propozycja usunięcia przyrostka nie dotyczyła zasady ogólnej, tylko pewnego konkretnego przypadku przypisania wartości do zmiennej: język c Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod. Zacznijmy od specyfikacji języka C99. W punkcie 6.4.4 podpunkt 5 na końcu strony 55 znajduje się taki zapis:
Na następnej stronie natomiast jest tabela, z której wynika, że typ stałej liczbowej w formacie dziesiętnym bez przyrostka będzie ustalany (dla omawianego przypadku) w sposób następujący (kolejność sprawdzania to int->long int->long long int):
Teraz kompilator musiałby przypisać wartość typu long int do zmiennej typu unsigned long int, więc musi dokonać niejawnej konwersji typu. Jednak biorąc pod uwagę, że liczba nie jest ujemna i mieści się w zakresie unsigned long int, żadnej utraty informacji czy też zmiany wartości też nie będzie. Problem może się pojawić w przypadku próby przypisania innej wartości, niż ta z przykładu. Należałoby tu jednak wziąć pod uwagę pewne zależności wynikające z ogólnej koncepcji programu:
Moje rozważania dotyczą cały czas przytoczonego wyżej konkretnego przypadku. W innych okolicznościach, kiedy nie jesteśmy pewni, nie pamiętamy lub nie wiemy, w jaki sposób kompilator potraktuje naszą stałą liczbową, zawsze warto jednoznacznie określić jej typ, nie jest to oczywiście błędem. W tym konkretnym przypadku jednak użycie przyrostka, zgodnie ze specyfikacją języka, nie jest niezbędne. |
Autor: | Zealota [ 12 kwi 2019, o 19:36 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
andrews, dzięki za sprecyzowanie. Średnio rozgarnięty programista zwykle nie zna takich szczegółów, nawet gdyby pogryzł specyfikację C99 Moja poprzednia odpowiedź była bowiem trochę prowokacyjna, żeby dowiedzieć się więcej. |
Autor: | Robert_1967 [ 12 kwi 2019, o 20:03 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Ładnie napisane. Odnośnie off topu, to popieram, ale dodam na koniec, że nieraz są osoby, które uczyły się informatyki, studiują itd. i mają już obeznanie, myślą programistycznie. Rozumieją te bity, bajty i cały ten "slang". Ponad to mają profesora, nauczyciela, który ma materiał do zrealizowania w odpowiedniej kolejności. Są sprawdziany i tego typu podobne rzeczy, gdzie musimy się dostosować, zaliczyć i to zmusza nas do pełnego opanowania materiału. Musi być dyscyplina, bo inaczej nie zaliczysz. Ja z kolei nie mam kompletnego przygotowania, jak również wiele podobnych osób i nam jest zdecydowanie trudniej, No i nie ma sprawdzianów, zliczeń i mamy wolna rękę, co skutkuje tym, co widać. No i niektórzy są urodzonymi matematykami, mają predyspozycje itd. Znam osobę, która po roku nauki wyczynia takie rzeczy, że szczena opada. No ale mnie to bardzo fascynuje i będę dalej się uczył i coś tam dłubał z czystej przyjemności. Koniec tematu i nie wracam do tego. Chciałem jeszcze raz się odnieść do tych typów. Zakładamy, że mamy dwa ciągi liczb. Oba mieszczą się w uint32. Ale kiedy wykonamy mnożenie na tych liczbach, to nagle okazuje się że wynik mieści się dopiero w 64 bitach. Przecież procesor musi gdzieś przechowywać ten wynik i musi mieć dla niego odpowiedni worek gdzieś w ramie, bo jak będzie za mały, to się nie zmieści. Ja tylko piszę w kontekście mojego samo myślenia. To nie jest podważanie Waszej opinii, ponieważ mam o wiele za mało wiedzy. Podobno kompilator sam sobie pomoże i naprawi błąd programisty, ale mi o tym nie powie, a ja będę sądził, ze napisałem poprawnie, bo przecież "działa". Jeszcze inny przypadek. Powiedzmy, że mamy dwie liczby , które mieszczą się w zakresie uint32 i wykonujemy mnożenie. Następnie dzielimy wynik przez kolejną zmienną i wynik mieści się w zakresie uint32, ale "przez chwilę" przed dzieleniem występowała sytuacja gdzie wynik mnożenia nie mieścił się w uint32, a procesor, czy też kompilator musi sobie z tym poradzić. To są momenty, kiedy czegoś do końca nie wiem i wychodzi kaszana. Niby rozumiem mechanizmy działania, ale brak kropki nad i w posiadanej wiedzy i to w różnych innych przypadkach odnośnie C. Pewnie z czasem tych luk będzie coraz mniej . Dla tego ktoś napisał, że zawsze należy dążyć do poprawności kodu, nie bacząc na to ,że kompilator zrobi za mnie robotę. Również czytałem, że jeśli jest potrzeba dodania np. UL, czy ULL, to powinniśmy dopisać do wszystkich zmiennych, które biorą udział w działaniu. Ale również czytałem, że jeśli w jakimś działaniu np. mnożeniu dwóch, czy więcej zmiennych dodamy do jednej z nich UL, czy ULL (bo taka jest potrzeba w tym konkretnym przypadku), to pozostałe zmienne równie przyjmą format UL, czy ULL mimo że nie jest dopisane do tych zmiennych. Różnie piszą i potem trzeba wybrać to co najwłaściwsze, a samemu można się pomylić. Trochę się rozpisałem, ale dobra. Kończę i pozdrawiam wszystkich czytających wątek. Jest bardzo dużo otwarć na stronie, ale żeby się wypowiedzieć, to cisza . |
Autor: | Robert_1967 [ 13 kwi 2019, o 17:35 ] |
Tytuł: | Re: Typy zmiennych-pytanie o poprawność w programie |
Jeszcze raz wielkie dzięki andrews za tak dokładne i precyzyjne wytłumaczenie tematu. Myślę, że rozwiało wszelkie wątpliwości. Trochę się napisaliśmy, ale warto było . Pozdrawiam wszystkich. |
Strona 1 z 1 | Strefa czasowa: UTC + 1 |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |