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



Teraz jest 22 mar 2026, o 15:06


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 4 ] 
Autor Wiadomość
PostNapisane: 20 lut 2013, o 21:13 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 lut 2012
Posty: 243
Lokalizacja: wlkp
Pomógł: 2

Witam,
pisałem program w C na PC i w międzyczasie natknąłem się na niespodziankę z przepełnianiem zmiennej typu unsigned int.
Zmienna typu unsigned short int zachowuje się w porządku, natomiast przepełnienie zmiennej unsigned int odbywa się jakby to była zmienna ze znakiem (signed). Nie mogę zrozumieć dlaczego tak się dzieje.

Przygotowałem fragmenty dla obu typów zmiennych, żeby zademonstrować o co chodzi:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


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


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


W konsoli otrzymujemy tym razem niezamierzone wartości:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Dlaczego w drugim przykładzie zmienna "b" nie zeruje się po dodaniu jedynki?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 20 lut 2013, o 22:49 
Offline
Użytkownik

Dołączył(a): 14 sty 2013
Posty: 36
Pomógł: 2

Jeżeli liczba by miała być:
unsigned int to jej maksymalna wartość to nie 0x7FFFFFFF czyli tak jak podajesz 2147483647 a 0xFFFFFFFF czyli 4294967295.
Z obliczeń po dodaniu 1 wychodzi liczba 0x80000000 a to dokładnie w ZU2 -2147483648.
Podsumowując, wytłumaczenie jest takie, że kompilator deklarację unsigned int traktuje jako signed int.

A jeszcze dodatkowo: problem nie dotyczy tylko tego przypadku, Sprawdź sobie proszę:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Wynika to z prostego faktu: operacja zmiany znaku x = -x realizowana w U2 jest jako x = (~x) + 1

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



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 lut 2013, o 12:12 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 lut 2012
Posty: 243
Lokalizacja: wlkp
Pomógł: 2

strzelec napisał(a):
Podsumowując, wytłumaczenie jest takie, że kompilator deklarację unsigned int traktuje jako signed int.

Dokładnie tak jak napisałem wyżej. Dziwna sprawa, że dla kompilatora nie ma różnicy akurat unsigned czy signed int. Nie przeszkadza mi to, ale jeżeli nie potrzebuję operować na liczbach ujemnych, to zdecydowanie bardziej komfortowe dla mnie jest korzystanie jednak z liczb bez znaku.
Dzięki za zaangażowanie, że chciało się Tobie sprawdzić. :)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 21 lut 2013, o 15:55 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 12 lut 2012
Posty: 243
Lokalizacja: wlkp
Pomógł: 2

Gwyn, właśnie doszedłem co było nie tak. :D

Otóż, specyfikator formatu był źle dobrany w funkcji printf(). Zwróć uwagę, '%d' służy do wyświetlania dziesiętnych liczb całkowitych ze znakiem, z kolei specyfikator '%u' służy do wyświetlania dziesiętnych liczb całkowitych bez znaku. Wystarczyła podmiana specyfikatora i wszystko działa jak należy - zmienna zeruje się. Faktycznie pomyliłem się przy inicjalizacji, bo powinno być oczywiście a=4294967295;



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: 4 ] 

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:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO