Czym różni się dodawanie całkowite od dodawania bez znaku ?
signed overflow to UB, a w unsigned jest zdefiniowany jako wrap around.
Np.
3000000000 + 3000000000; // UB
3000000000u + 3000000000u; // 6000000000 % (UINT_MAX+1)
Co oznacza UB i wrap around?
Undefined behavior, czyli niezdefiniowane zachowanie. Jako programiście nie wolno Ci do tego dopuścić.
Wrap around - zawinięcie za maksymalną wartością. UINT_MAX + 1 == 0
Czyli w dodawaniu całkowitym dostaniemy nadmiar?
Będzie UB. Nie jest powiedziane co się stanie.
A jeśli przepełniłbym liczby bez znaku ?
To będzie wrap around.
W jakim sensie to zawinięcie?
Obcięte zostaną bity najbardziej po lewej, albo inaczej mówiąc, wartości będą zawsze modulo UINT_MAX+1
. Tak jak pokazałem to wyżej:
3000000000u+3000000000u; // 6000000000 % UINT_MAX
UINT_MAX + 1 == 0;
UINT_MAX + 5 == 4;
Czyli w dodawaniu bez znaku przenosimy bity ?
w dodawaniu bez znaku dodajemy bez znaku, a potem obcinamy najwyższe bity (co jest jednoznaczne z operacją modulo UINT_MAX+1
)
I z mnożeniem jest tak samo ?
Tak. Uprzedzając pytanie, wyjście poniżej minimalnej wartości też nazywa się overflowem (czyli duże wartości ujemne)