Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 28 lut 2026, o 23:48


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 
Autor Wiadomość
PostNapisane: 11 maja 2015, o 17:43 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1988
Lokalizacja: Lipsko
Pomógł: 125

Czym jest promocja domyślna powinien wiedzieć w zasadzie każdy kto zaczyna zabawę z C i korzysta z liczb większych niż 16-o bitowe.
Straciłem ostatnio jakieś 3-4h na szukaniu błędu i o to wnioski, które być może komuś się przydadzą... a może po prostu znowu czegoś nie wiem ;)

Do rzeczy, miałem w programie taką o to linię:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Na pierwszy rzut wszystko ok. Wszystkie zmienne (A, xw, kA) to uint16_t, a wynik w "A" w założeniach programu nigdy nie przekracza 60000, więc za wszelkimi źródłami do jednego z wyrażeń w obliczeniach (a konkretnie do stałej w wyrażeniu) dodajemy "UL" jako promocja do 32bit i powinno hulać... a tu zonk :o Po wymnożeniu tego co w nawiasie i przekroczeniu 16-u bitów przez 10 dzielone jest tylko 16 bitów, a przecież jest UL przy stałej... o co więc chodzi ?? Jedziemy dalej, następna poprawka już w nieco inny sposób jak podaje wszelka literatura:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


I co? Chciało by się powiedzieć g..o (niestety). Sytuacja z wynikiem dokładnie jak w pierwszym przykładzie. No dobra, to może na piechotę jakiś szybki test... dodałem zmienną 32bit:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


I mamy sukces !!! Dopiero taka konfiguracja pozwoliła wyrwać mi się z błędu (nawiasem mówiąc po wypiciu pół puszki piiii..eee...soku jabłkowego :mrgreen: Podobno jego niewielka ilość rozjaśnia umysł 8-)
Minutę później miałem już taką działającą konfigurację:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jak widać TYLKO działanie mnożenia jest uwzględnione do promocji(!).

Stąd jasno wynika, że albo promocja nie dotyczy wszystkich działań w linii (jak podają wszelkie źródła, które w pośpiechu wertowałem), albo znowu czegoś nie wiem... W każdym razie moje doświadczenia pokazały, że należy uważać co się promuje. Prawdopodobnie "dzielenie" z założenia przez kompilator da wynik 16 bitowy stąd jest on "mądrzejszy" od programisty...
Zachęcam do przeprowadzenia testów i podzielenia się wnioskami.
Zapewniam, że z palca powyższego nie wyssałem, a kilku godzin, które przez to straciłem potraktuję jako naukę (bo nikt mi ich już nie odda :) ), aby nie wierzyć tak do końca we wszystko co się czyta ;)

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 maja 2015, o 18:12 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

Pisałem to już dość dawno:

http://atnel.pl/domyslna-promocja-do-typu-int.html

niestety jakoś mało ludzi zagląda ... nie wiem czemu.

prawidłowo powinno być tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


bo coś takiego:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

nie ma sensu i nie ma się co dziwić, że działa tak samo źle jak to pierwsze.....

Wszystko przy założeniu że xw i kA są zmiennymi 16-bitowymi

Zrozum promocja DZIAŁA ZAWSZE DOBRZE ale w ramach JEDNEGO WYRAŻENIA - trzeba o to zadbać samemu .... Jak masz coś takiego:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


to widać tam JEDNO wyrażenie takie oto:

Kod:
(xw*kA)


i nie dziw się że będzie ono skopane pomimo że masz 10UL albo że masz przed wyrażeniem (uint32_t) .... bo to ostatnie rzutowanie (uint32_t) to tylko twoje pobożne życzenie żeby wynik tego skopanego działania był rzutowany na uint32_t a nie żeby działanie było realizowane w trybie 32-bitowym

WYSTARCZY JEDNĄ ZMIENNĄ w ramach NAJMNIEJSZEGO wyrażenia rzutować na uint32_t i już będzie dobrze, to samo by ci wyszło gdybyś miał jedną z tych zmiennych typu uint32_t , wtedy nie musiałbyś rzutować......

Reasumując jeśli masz:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


to możesz robić skomplikowane obliczenia w jednej linii ale musisz pamiętać o domyślnej promocji i w związku z tym rzutować co najmniej tak:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


mam nadzieję, że proste jak już się zrozumie co to są WYRAŻENIA w C

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 maja 2015, o 18:31 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1988
Lokalizacja: Lipsko
Pomógł: 125

Hehe, Mirku, uwierz czytałem to ze 3 razy z myślą, że coś musiałem przeoczyć, a jednak nie wynikło z tego nic jasno. Wiele przykładów i innych źródeł przejrzałem i w większości przypadków przykłady były albo bardzo proste (zwykłe mnożenie jak u Ciebie), albo jednowyrażeniowe, które jednoznacznie nic nie pokazały. Po moich bojach wiem już dokładnie jak to stosować i stąd też mój post dla potomnych, w każdym razie zachęcam Cię do uzupełnienia blogu przynajmniej o ten jeden mój przykład, bo jeśli ja się na tym złapałem to zapewne i będą następni ;) Nawiasem mówiąc żyłbym dalej w błogiej nieświadomości i z błędem w programie gdyby nie wrodzona ciekawość co by było gdyby... W praktyce w moim programie nawet wymnożone liczby podczas testów nigdy nie przyjmowały wartości więcej niż 16 bit chociaż rezerwę dałem bardzo dużą dla końcowego wyniku (bo parametry użytkownik ustawia sam i zakres mógłby być przekroczony) jednak zacząłem kombinować żeby sprawdzić ile jakaś tam opcja wytrzyma i jakież było moje zdziwienie gdy nie mogłem dobić do końca zakresu... Oddał bym klientowi urządzenie, a za parę dni telefon, że nie działa :)

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 maja 2015, o 18:34 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

Widzisz bo z tą promocją to jest tak:

jak nie dotkniesz - jak nie przetestujesz - to najczęściej nie zrozumiesz.

Jak już dotkniesz i przetestujesz, zobaczysz o co chodzi to później już problemów nie będzie i okaże się że temat jest w sumie prosty jak drut ;)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 11 maja 2015, o 19:11 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 22 paź 2013
Posty: 1988
Lokalizacja: Lipsko
Pomógł: 125

A no dokładnie jest tak jak mówisz :) Trza pomacać i tyle... 8-)

_________________
http://www.sylwekkuna.com



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO