co w tej funkcji nie gra? jak printuje argument dest to mam śmieci z pamięci :/
void to_bin(unsigned int src, char* dest)
{
for(int i = 31; (int)src > 0; i--)
{
*(dest+i) = src%2 + '0';
src/=2;
}
}
char L1[32];
to_bin(0xffffffff, &L1[0]);
for(int i = 0; i<32; i++)
{
printf("%c", *(L1+i));
if( i%8 == 0 )
{
printf(" ");
}
}
ok, wystarczyło zmienić warunek src>0 na i>=0
mam tylko jeden pomysł ale wydaje mi się głupi, może jak dziele inta to zapisał go na float i wynik nigdy 0 nie jest? jeśli znasz odpowiedź to poproszę o sprostowanie.
Twoja funkcja to_bin
przyjmuje jako pierwszy parametr zmienną typu unsigned int
. W pętli castujesz uinta na int'a
, a z racji, że większość systemów operacyjnych używa two's complement (https://en.wikipedia.org/wiki/Two%27s_complement) do reprezentacji liczb to Twoja pętla nigdy się nie wykona.
Dlatego, że 0xffffffff
to 2^32-1
w reprezentacji unsigned int
, ale -1
w reprezentacji int
. Skoro pętla w funkcji nigdy się nie wykona to tablica jest niezainicjalizowana i drukowałeś losowe bajty pobrane ze stosu.
Swoją drogą to Integer overflow
jest częstym vulnem w oprogramowaniu, który można czasem wykorzystać do manipulacji alokowaną pamięcią i taki głupi błąd może w efekcie dać atakującemu dostęp do systemu ;) Także trzeba uważać
A jeśli chodzi o dzielenie inta to typ zmiennej podczas wykonywania operacji arytmetycznych się nie zmienia - o to się nie martw.
EDIT Oczywiście castowanie było w Twoim przypadku niezamierzone, ale nie jest to integer overflow
, ponieważ nie została zmieniona wartość zmiennej, a jedynie sposób jej rozumienia. Ale o integer overflow też możesz sobie poczytać ze względu na to co napisałem powyżej.
Wkurza mnie studenckie/uczelniane mówienie o takich zagadnieniach jako "konwersja do postaci binarnej" czy toBin() itd... Nie ma żadnych powodów do konwersji. Liczby w naszych int'ach są binarne same przez siebie w sposób doskonały *), i nie mogą być "lepiej binarne". Myślę, że to nie wina konkretnego studenta (juniora), tylko że uczący go już zagubili rozumienie binarności.
Wszystkie podobne zagadnienia w rzeczywistości są "przygotuj liczbę do drukowania w formacie binarnym" czy printAsBin() albo formatAsBinString()
Coś czuję, że wkurzę kilku szybkich programistów, że czepiam się słowek. Odpowiem: tak, słowa są ważne, a nawet bardzo ważne. Problemy podstawowe są bardzo ważne. Potem doświadczony programista języka X odkrywa, że jego język od wielu lat oszukuje bo 0.2+0.1 == 0.3000000075 (autentyk z tego forum). Przykład z nieco innego obszaru, ale obecnie wykształconym programistom brakuje takich prozaicznych podstaw.
*) są nieliczne platformy, rzadkie, gdzie kodowanie wewnętrzne jest dziesiętne, np BCD, ale o tak wyrafinowane przypadki nikt nie pyta
#include <iostream>
#include <bitset>
int main()
{
std::bitset<32> b(23124213);
std::cout << b;
return 0;
}
https://wandbox.org/permlink/f5bHBpkRSMSIEjhb
ups nie spojrzałem na tag c99, nieważne
integer overflow
(ponieważ wtedy byłoby to UB), tylko ma miejsce sytuacja opisana w C116.3.1.3
(https://stackoverflow.com/questions/9498190/is-conversion-from-unsigned-to-signed-undefined).integer overflow
bo tą wartość można jako int reprezentować. Tylko czym w takim razie jest integer overflow? Nadpisanie inta większą wartością niż INT_MAX lub mniejszą niż INT_MIN. Tutaj castowanie na wartość -1 było niezamierzone to jak ten błąd inaczej nazwać?(a + 1) - 1
niekoniecznie musi być równea
(ponieważ jest to UB), lecz(int) (unsigned int) -1
może znów dać w wyniku-1
(o ile implementacja tak funkcjonuje, ponieważ jest to implementation-defined).