Jeśli jesteś właścicielem tej strony, możesz wyłączyć reklamę poniżej zmieniając pakiet na PRO lub VIP w panelu naszego hostingu już od 4zł!
2013-01-11    Programowanie, Kod, C, C++, Algorytmy, Spoj

Dobiega do końca już drugi tydzień roku. Mam nadzieję, że każdemu udało się go nie zmarnować ;). Osobiście ten tydzień spędziłem na "klepaniu" zadań ze Spoj'a, pisaniu skrypcików w Perlu oraz w Ruby. Miałem też przyjemność analizowania trzech, bardzo ciekawych crack me. Ale nie o tym dziś ;)

Udało mi się znaleźć bardzo ciekawe zadanko. Oto jego treść . Na pierwszy rzut oka może wydawać się dosyć trudne, ale przy głębszym zastanowieniu można dojść do wniosku, że można go rozwiązać na dwa, różne sposoby:
1. Matematycznie - algorytmicznie
2. Albo "Programistycznie" - odwołując się do pamięci zapisanego float'a

Pierwszy z nich jest moim zdaniem trudny, a przynajmniej pracochłonny. Za to drugi jest dla mnie idealny i na nim dziś się skupię. Mając troszeczkę wiedzy na temat architektury x86, rozwiązanie nie powinno stanowić problemu. Implementacja tej funkcji wygląda u mnie tak:
 
//implementacja f. DecToHex(int)
 
void printfloat(float a)
{
    unsigned char *buf = (unsigned char*)(&a);
 
    DecToHex(buf[3]);
    cout << " ";
    DecToHex(buf[2]);
    cout << " ";
    DecToHex(buf[1]);
    cout << " ";
    DecToHex(buf[0]);
    cout << endl;
}
 
A teraz krok po kroku dlaczego to wszystko działa ;d.
 
unsigned char *buf = (unsigned char*)(&a);
 
W tej linijce zastosowałem rzutowanie adresu zmiennej a na typ unsigned char* . Oznacz to, że pointer buf wskazuje teraz na pierwszy bajt przesłanej zmiennaj. Typ jest bez znaku, ponieważ wartości te właśnie tak mamy podać. Dodatkowo jeszcze musimy je zamienić na hex'a.

Liczby na architekturze x86 są przechowywane w Little Endian (tzn. odwrotnie niż "fizycznie"), przez co musimy czytać je w odwrotnej kolejności. Wyświetlamy je jakby Big Endian(architektura np. SPARC, Motorola 68000).

Tak jak widzimy, zadanie to nie było trudne. Wystarczyło mieć pojęcie na temat architektury x86 oraz jak można "sprytnie" operować wskaźnikiem.

Na Spoj'u nie ma za wiele prawidłowych rozwiązań tego programu. Może dlatego, że w większości "ludność" ta zajmuje się bardziej algorytmiką w sensie matematycznym(logicznym), niż w sensie "praktycznym". System na stronie przyjmuje praktycznie tylko programy w C/C++, lecz jeśli ktoś jest chętny, to jako praca domowa może napisać ten programik w języku assembler.
Dodaj komentarz:
Nick:
URL(opcjonalnie):