int to binary 32b

Odpowiedz Nowy wątek
2019-08-09 11:46
0

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;
    }
}
edytowany 1x, ostatnio: Mateusz Janiak, 2019-08-09 12:01

Pozostało 580 znaków

2019-08-09 12:13
0

Pasowałoby wiedzieć jaki Ty ten argument dest przekazujesz podczas wywołania funkcji


Pozostało 580 znaków

2019-08-09 12:16
0
char L1[32];
    to_bin(0xffffffff, &L1[0]);

    for(int i = 0; i<32; i++)
    {
        printf("%c", *(L1+i));
        if( i%8 == 0 )
        {
            printf(" ");
        }
    }

Pozostało 580 znaków

2019-08-09 12:21
0

ok, wystarczyło zmienić warunek src>0 na i>=0

Pozostało 580 znaków

2019-08-09 12:23
1

A wiesz dlaczego tak się stało czy polegasz na zgadywaniu?


Pozostało 580 znaków

2019-08-09 12:30
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.

Pozostało 580 znaków

2019-08-09 12:41

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.


edytowany 2x, ostatnio: Shizzer, 2019-08-09 13:35
U2 nie jest cechą systemu operacyjnego, a architektury procesora + to rzutowanie nie prowadzi do integer overflow (ponieważ wtedy byłoby to UB), tylko ma miejsce sytuacja opisana w C11 6.3.1.3 (https://stackoverflow.com/que[...]-unsigned-to-signed-undefined). - Patryk27 2019-08-09 12:49
No racja, nie jest to 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ć? - Shizzer 2019-08-09 13:13
Overflow następuje w wyniku operacji, które mają wpływ na wartość. Casting nie zmienia wartości, a sposób jej rozumienia, dlatego też w tym wypadku overflow nie ma miejsca, a samo rzutowanie nie jest błędem (w sensie, że nie stanowi UB). Zauważ, że (a + 1) - 1 niekoniecznie musi być równe a (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). - Patryk27 2019-08-09 13:21
"większość" == "wszystkie". architektury w których liczby całkowite ze znakiem nie są U2 chyba już dawno wymarły. - Azarien 2019-08-10 21:44

Pozostało 580 znaków

2019-08-10 20:07
2

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

edytowany 4x, ostatnio: AnyKtokolwiek, 2019-08-10 20:12

Pozostało 580 znaków

2019-08-11 20:19
1
#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

edytowany 1x, ostatnio: gośćabc, 2019-08-11 20:23

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0