StyleGame

Online Tutorials

Va rog sa faceti cunoscut forumu. Cum puteti ajuta? De preferat la status pe yahoo messenger massuri etc. Va urez bafta in a ne ajuta cu respect echipa stylegame

    C++ - Constante Binare

    Distribuiţi
    avatar
    CYobY
    Administrator
    Administrator

    Mesaje : 197
    Data de inscriere : 04/10/2009
    Varsta : 24
    Localizare : VASLUI

    C++ - Constante Binare

    Mesaj Scris de CYobY la data de Sam Oct 24, 2009 4:23 am

    C++ ca limbaj de programare, suporta 3 baze de numaratie: normalul decimal, folositorul hexadecimal si total inutilul si eventual creatorul de probleme octal. Ma refer aici la conventia de scriere a unui numar in octal: orice numar incepand cu cifra 0. De aici confuzii de genul 0033 fiind de fapt 27 si nu 33 prefixat cu 0-uri pt. frumusete sau stil:)

    Ca o paranteza curioasa, numerele de genul 08, 09 sunt total ilegale in C/C++, deoarece evident octul are cifre numai de la 0 la 7. Incercati de exemplu
    int i = 08;

    in orice compilator si urmariti efectul!

    C/C++ fiind limbaje de nivel mediu, operand cu concepte per masina: pointeri, sizeof(), etc, ar fi trebuit sa contina si posibilitatea de a scrie numere direct in baza 2 (in binar) care de mult ori ar fi fost de dorit decat blamatul octal. Cei care lucreaza des cu operatii pe biti, cred ca ar fi apreciat cel mai mult o atare functionalitate.
    Exista compilatoare care suporta numere introduse direct in baza binar, de exemplu GCC, dar mult de preferat ar fi fost o standardizare.
    Bineinteles ca se pot scrie functii specializate pentru asa ceva (conversie din/in binar) cand este nevoie, dar cum orice programator de C/C++ stie, o functie inseamna extra timp la rulare, chiar daca in ziua de azi e de ordinul mili/nanosecundelor. Deci inca odata, o solutie din compilator ar fi perfecta!

    Desi C++ nu ofera asa ceva, ofera in schimb suportul pentru a construi asa ceva...
    Ma refer aici la template-uri si mecanismul de specializare a acestora. Prin utilizarea unei clase template specializata pe int, se pot realiza in C++ constructii in baza 2, care vor fi evaluate de compilator automat drept simple numere in baza 10!
    De examplu putem avea ceva de genul:

    binar<11>::valoare

    care va fi automat evaluat si inlocuit de compilator (deci fara nici o implicatie asupra rularii programului) cu valoarea in baza 10:3
    Codul care face posibil asa ceva:

    /*
    * determinam la inceput cel mai mare integer care poate fi
    * descris (atomic) pe o masina, pt a beneficia de cele mai
    * multe lungi secvente de cifre pe o masina de 32 biti:
    * 'long'(dword din asm) de maxim 10 cifre pe masini x86
    * 'long long' de maxim 19 cifre pe masini x64
    * (long long exista si pe masina de 32 biti, dar va
    * fi simulat sau truncat)
    */
    typedef long long longest_t;

    /*
    * clasa template, specializata numai pentru longest_t
    * tot secretul aici este valoarea elementului 'value' din
    * enum, care nu e precizat direct ci lasat sa fie evaluat
    * prin recursivarea in alte instante ale clase template,
    * adica numarul nostru 'deghizat' in binar (el fiind tot
    * scris in decimal), va fi impartit pana la epuizare la
    * 10, retinand resturile impartirii (adica izoland cifra
    * cu cifra) apoi reinmultind cu 2 pt a schimba baza.
    */
    template
    class bin
    {
    public:
    enum {
    value = (N % 10) + (bin::value << 1)
    };
    };

    /*
    * ne vom opri la ultima cifra, pt a ingadui incheierea
    * lantului recursivitatii si 'reimpachetarea' stivei
    * acest lucru este posibil datorita specializarii (adica
    * tratarii separate a) template-ului pt. cazul cand
    * numarul devine 2 (acest lucru e 'fortat' de noi mai
    * jos...)
    */
    class bin<2>
    {
    public:
    enum {
    value = 0
    };
    };


    Desi template-urile au realizat toata treaba pentru noi si sunt instrumente perfecte aici, operand numai in timpul compilarii, vom apela totusi la fratii lor 'vitregi': macrocomenzile, din doua motive:

    1. e destul de ciudat a scrie bin<10>::value de fiecare cand vrem numarul 2 scris in binar
    2. dupa cum am spus in introducere octalul ne poate juca feste, asa ca vom prefixa invizibil un 2 in fata oricui numar in noua baza, pt a inlatura orice confuzii si pt a avea si un mecanism simplu de stop.
    Macro-ul este:

    #define binary(n) bin<2>::value


    De notat aici operatorul ## al preprocesorului, care lipeste direct doi operanzi sau paramatri (din a##b va rezulta ab).

    Cu toate acestea puse la punct, nimeni nu ne mai opreste sa scriem de acum incolo:


    binary(11) = binary(011) = binary(000000000000000011) pentru 3
    binary(11111111) pentru 255
    binary(100000000000000000) pentru 131072
    binary(111111111111111111) pentru 262143 (maximumul in binar pe un sistem pe 32biti)


    _________________
    RESPECT

      Acum este: Lun Aug 20, 2018 3:14 am