• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Reprezentacja liczby float cpp

Object Storage Arubacloud
+1 głos
1,772 wizyt
pytanie zadane 11 stycznia 2016 w C i C++ przez robert9620 Stary wyjadacz (11,640 p.)

Witam. Chciałbym wypisać zmienną typu float dokładnie tak jak zapisana jest w komputerze. Tzn np. 1 jako "3f 80 0 0". Znalazłem taki kod, który działa :

void printfloat(float liczba){
	for (int i = sizeof liczba-1; i>=0; --i){
		printf("%x ",(((const unsigned char*)&liczba)[i]));
	}
}

Jednak czy mógłby mi ktoś wyjaśnić jak to dokładnie działa ? Mile widziane linki do dokumentacji. Czy da się to zapisać za pomocą cout-ów ?

1 odpowiedź

+3 głosów
odpowiedź 11 stycznia 2016 przez MetGang Nałogowiec (34,360 p.)
wybrane 12 stycznia 2016 przez robert9620
 
Najlepsza
Float zajmuje 4 bajty, unsigned char 1 bajt. Ustawiasz adres (wskaźnik) 1 bajtowego uchara na jeden z czterech bajtów floata, wypisujesz i następnie przestawiasz wskaźnik na kolejny bajt itd (pętlą). W dużym skrócie, odczytujesz pamięć bajt po bajcie i wypisujesz jej wartość.
komentarz 11 stycznia 2016 przez robert9620 Stary wyjadacz (11,640 p.)

Wiem jak działa pętla. Bardziej ciekawi mnie ten zapis "printf("%x ",(((const unsigned char*)&liczba)[i]));". Jak to zastąpić coutem ? Co to jest "const unsigned char*" i czemu muszę operować na wskaźnikach ?

komentarz 11 stycznia 2016 przez MetGang Nałogowiec (34,360 p.)

printf() jest funkcją z języka C wypisującą dane w konsoli. W C++ wyglądałoby to tak:

cout << ((const unsigned char*)(&liczba))[i];

const jest tu zapewne tylko w celach optymalizacji (read-only), unsigned char* to wskaźnik do 1 bajtowego (unsigned żeby nie było ujemnych, 0-255) chara. W pamięci float wygląda mniej więcej tak:

[0000 1100] [0000 1000] [0000 1100] [0010 0010]

Natomiast (pierwszy) char tak:

[0000 1100]

Teraz bierzesz adres floata i bajt po bajcie skaczesz i wypisujesz jego wartość:

[0000 1100] // to jest ten const unsigned char* [i], jego wypisujesz
[0000 1100] [0000 1000] [0000 1100] [0010 0010] // to jest float

// obejście pętli
            [0000 1000]
[0000 1100] [0000 1000] [0000 1100] [0010 0010]

// obejście pętli
                        [0000 1100]
[0000 1100] [0000 1000] [0000 1100] [0010 0010]

// obejście pętli
                                    [0010 0010]
[0000 1100] [0000 1000] [0000 1100] [0010 0010]

 

komentarz 12 stycznia 2016 przez robert9620 Stary wyjadacz (11,640 p.)
Oj trochę się zapędziłem i już dałem najlepszą odpowiedź, a po skompilowaniu jednak nie działa. Kod z cout-em, który dałeś zwraca dla jedynki "?C", a ten printf "3f 80 0 0".
komentarz 12 stycznia 2016 przez MetGang Nałogowiec (34,360 p.)

Raczej działa, tylko problem jest w systemie zapisu. printf() z argumentem %x zwraca liczbę w systemie heksadecymalnym. 3F w HEX to 63 czyli znak ASCII ?, a 80 w HEX to 128 co już nie jest standardowym drukowalnym znakiem, pozostałe zera to '\0' czyli nic nie drukuje. Spróbuj tak:

#include <iomanip>
std::cout << std::hex << ((const unsigned char*)(&liczba))[i];

100% pewien nie jestem tego zapisu.

komentarz 12 stycznia 2016 przez robert9620 Stary wyjadacz (11,640 p.)
Nic nie dało. Dane wyjściowe dokładnie te same - "?C"
komentarz 12 stycznia 2016 przez MetGang Nałogowiec (34,360 p.)
#include <iomanip>
std::cout << std::hex << (unsigned int)(((const unsigned char*)(&liczba))[i]);

W sumie powinno się jeszcze na inta to dać...

komentarz 12 stycznia 2016 przez robert9620 Stary wyjadacz (11,640 p.)
Działa! Wielki plus dla Ciebie ! Co prawda bibliotek iomanip jest zbędna, ale reszta kodu się zgadza. Jeszcze trzeba dodać spacje w odpowiednich miejscach, żeby wypisało dokładnie tak samo, ale to już nie problem. Jeszcze raz dziękuje :)

Podobne pytania

0 głosów
2 odpowiedzi 2,688 wizyt
pytanie zadane 7 kwietnia 2016 w C i C++ przez Adrian1999 Nałogowiec (34,570 p.)
0 głosów
1 odpowiedź 489 wizyt
pytanie zadane 16 lutego 2016 w C# przez niezalogowany
+1 głos
2 odpowiedzi 659 wizyt
pytanie zadane 5 grudnia 2015 w C# przez rafalx200 Początkujący (250 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...