int to binary 32b

int to binary 32b
Mateusz Janiak
  • Rejestracja:prawie 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:24
0

co w tej funkcji nie gra? jak printuje argument dest to mam śmieci z pamięci :/

Kopiuj
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
Shizzer
  • Rejestracja:prawie 8 lat
  • Ostatnio:4 miesiące
  • Postów:231
0

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


Mateusz Janiak
  • Rejestracja:prawie 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:24
0
Kopiuj
char L1[32];
    to_bin(0xffffffff, &L1[0]);

    for(int i = 0; i<32; i++)
    {
        printf("%c", *(L1+i));
        if( i%8 == 0 )
        {
            printf(" ");
        }
    }
Mateusz Janiak
  • Rejestracja:prawie 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:24
0

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

Shizzer
  • Rejestracja:prawie 8 lat
  • Ostatnio:4 miesiące
  • Postów:231
1

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


Mateusz Janiak
  • Rejestracja:prawie 6 lat
  • Ostatnio:prawie 5 lat
  • Postów:24
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.

Shizzer
  • Rejestracja:prawie 8 lat
  • Ostatnio:4 miesiące
  • Postów:231
3

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
Patryk27
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/questions/9498190/is-conversion-from-unsigned-to-signed-undefined).
Shizzer
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ć?
Patryk27
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).
Azarien
"większość" == "wszystkie". architektury w których liczby całkowite ze znakiem nie są U2 chyba już dawno wymarły.
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:dzień
  • Postów:3561
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


Bo C to najlepszy język, każdy uczeń ci to powie
edytowany 4x, ostatnio: AnyKtokolwiek
gośćabc
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Szczecin
  • Postów:500
1
Kopiuj
#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
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)