Převod z binární soustavy do char v desítkové soustavě – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Převod z binární soustavy do char v desítkové soustavě – C / C++ – Fórum – Programujte.comPřevod z binární soustavy do char v desítkové soustavě – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
oxidián0
Grafoman
14. 3. 2015   #1
-
0
-

Potřeboval bych poradit jak udělat následující. Mám číslici 75 v desítkové soustavě (uint32_t). Binárně je to

01 00 10 11 a potřeboval bych převést jednotlivé dvojce na char ale v desítkové soustavě.

Tedy 01 => '1', 00 => '0', 10 => '2', 11 => '3'

jednak nevím jak se převádí za 75 na binární (ale to snad ani nebude třeba?)

Napadá mě smyčka a posun do leva, ale to mi příjde neefektivní, protože bych k tomu potřeboval pomocné proměnné a provádět přiřazování což samo o sobě je časově náročnější operace než čtení. Jedná se jen o 4 číslice.

A druhak nevím jak převést tu binární dvojci na char v desítkové soustavě.

Nahlásit jako SPAM
IP: 78.45.199.–
ondrej39+1
Věrný člen
14. 3. 2015   #2
-
0
-

#1 oxidián
Najdi si na googlu převod z desítkové do binární soustavy v C, pak výsledný řetězec charů rozděl po dvou a na každou dvojici použij třeba atoi.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
ingiraxo+15
Grafoman
14. 3. 2015   #3
-
0
-

#1 oxidián

string homework(const int& value)
{
    string bin = bitset<8>(value).to_string();
    ostringstream oss;

    for (size_t i = 0; i < bin.length(); i += 2) {
        char c[] = { bin.at(i), bin.at(i + 1), '\0' };
        oss << bitset<32>(c).to_ulong();
    }
    return oss.str();
}

int main()
{
    cout << homework(75); // 1023
    return EXIT_SUCCESS;
}
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
oxidián0
Grafoman
14. 3. 2015   #4
-
0
-

@ingiraxo:

Promiň, zapomněl jsem zmínit že to potřebuju v C.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
14. 3. 2015   #5
-
0
-

ondrej39:

to je úplný nesmysl co říkaš, protože přece nebudu převádět číslo na řetězec charů reprezentující binární číslice?

Nahlásit jako SPAM
IP: 78.45.199.–
ondrej39+1
Věrný člen
14. 3. 2015   #6
-
0
-

#5 oxidián
No dobře, až mi ukážeš, jak třeba do integeru nacpeš 110010101100001011011011, tak uznám, že převádět číslo v desítkové soustavě na řetězec charů je zbytečné :-).

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
14. 3. 2015   #7
-
0
-

ondrej39:

tak to číslo program vidí binárně ne? Kdyby ne tak bys nemohl provádět bitový posun

Nahlásit jako SPAM
IP: 78.45.199.–
ondrej39+1
Věrný člen
14. 3. 2015   #8
-
0
-

#7 oxidián
Bitový posun ale můžeš provádět na číslech, na nichž to jde. Vem si například 32bitový signed integer, ten má rozmezí -2 147 483 648 až 2 147 483 647. Tedy horní hranice je 2 miliardy 147 milionů 483 tisíc 647. A vyšší číslo do integeru prostě nedáš kvůli OverflowException.

Když horní hranici vyjádříš v dvojkové soustavě, dostaneš 1 111 111 111 111 111 111 111 111 111 111. Takové číslo je v desítkové soustavě 1 kvintilion 111 kvadriliard 111 kvadrilionů 111 triliard 111 trilionů 111 biliard 111 bilionů 111 miliard 111 milionů 111 tisíc 111. Jestli se ti povede do běžného integeru narvat 1 kvintilion, budeš asi první na světě.

BTW: Kvintilion nenacpeš ani do 64bitového unsigned integeru, jediná možnost pro vyjadřování čísel ve dvojkové soustavě je prostě přes pole znaků.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
14. 3. 2015   #9
-
0
-

Mě jde jen o 4 číslice tedy o čtyři mocniny. čtyři posuny doleva. nic víc

Něco jak psal ingiraxo ale v C, tomu jeho kodu c C++ nerozumim

Nahlásit jako SPAM
IP: 78.45.199.–
ondrej39+1
Věrný člen
14. 3. 2015   #10
-
0
-

#9 oxidián
I tak se to jinak nedělá. Prostě pole charů. (Udělal ti to tak i ingiraxo, akorát namísto pole charů používá string z C++.)

ingiraxo na převáděí používá bitset, ale převést číslo z dekadické do binární soustavy můžeš udělat normálně modulem a následným podělením dvěma. Výsledky narvat do toho pole charů, jak jsem psal, pak to projet for cyklem a prvky i a i+1 znovu převést nazpátek do dekadické soustavy.

Jinak toto nejsou žádné složité operace, fakt ne. Je to pár cyklů dohromady s tím, že si musíš ohlídat pár indexů. To je úplně celé.

Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
14. 3. 2015   #11
-
0
-

Nechci dělit, dělení je pomalé.

Nahlásit jako SPAM
IP: 78.45.199.–
ondrej39+1
Věrný člen
14. 3. 2015   #12
-
0
-
Nahlásit jako SPAM
IP: 46.39.172.–
Inject all the dependencies!
oxidián0
Grafoman
14. 3. 2015   #13
-
0
-

haha zrovna ho studuju, tos nemusel posílat. Ale nevím jak zapsat binární jedničku (bit) do čísla? Protože musím tu detekovanou hodnotu někam zapsat. Tak já mám proměnnou uint16_t ch=0; a do toho chci zapsat tu zjištěnou hodnotu. Ta hodnota má jeden bit, ale jak zapsat bit na první místo a pak bit na druhé místo zprava?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
14. 3. 2015   #14
-
0
-

Proc se tu resi binarka, kdyz mi to pripada, ze chce ctyrkovou soustavu.. Samozrejme pan "bit shift je pomalej" predpoklada, ze bude potreba dalsich promennych (coz ani moc neni)

uint32_t neco = 75;
char vystup[17] = {0};
char * pv = vystup+16;
while (neco > 0) {
  *(--pv) = '0' + (neco&3);
  neco >>= 2;
}
printf("Ctyrkova: %s\n",pv);
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
14. 3. 2015   #15
-
0
-

Tak jsem to dokázal, jen se chci ještě zeptat jestli se to dá nějak udělat aby se k neměnilo. Protože se k mění, tak jsem musel udělat 3 kopie k a do každého příkazu dát samostatnou kopii, abych pokaždé pracoval s tím původním číslem 75.

uint16_t k,kk,kkk,kkkk;
// unsigned char a,b,c,d;
uint32_t n;
k=kk=kkk=kkkk = 75;
int c_ = 15; n = (uint32_t) k; printf("%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }

n = k & ~(0b11111100); // delete pair of bits
printf("\n%d\n",k);
c_ = 15; printf("\n%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }
n = (kk & ~(0b11110011)) >> 2 ; // delete pair of bits
printf("\n%d\n",kk);
c_ = 15; printf("\n%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }
n = (kkk & ~(0b11001111)) >> 4; // delete pair of bits
printf("\n%d\n",kkk);
c_ = 15; printf("\n%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }
n = (kkkk & ~(0b00111111)) >> 6; // delete pair of bits
printf("\n%d\n",kkkk);
c_ = 15; printf("\n%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }

Nahlásit jako SPAM
IP: 78.45.199.–
ingiraxo+15
Grafoman
14. 3. 2015   #16
-
0
-

#15 oxidián
ok, verze č.2, pokusil jsem se nepoužít žádný dělěno, modulo apod.. :-D i když to vypadá neefektivně tak tomu tak není, je to poměrně rychlý 

void homework(int n, char* r)
{
    int i,j,k,x;
    char t[3] = { 0 };
    for (i = 7, j = 1, k = 4; i >= 0; --i, n >>= 1, --j) {
        *(t + j) = (n & 1) + '0';
        if (j == 0) {
            if (*(t + 1) == '1' && *t == '1') x = '3';
            else if (*(t + 1) == '1') x = '1';
            else if (*t == '1') x = '2';
            else x = '0';
            *(r + --k) = x;
            j = 2;
        }
    }
}

int main()
{
    char r[5] = { 0 };
    homework(75, r); // 1023
    puts(r);
    return EXIT_SUCCESS;
}
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
oxidián0
Grafoman
14. 3. 2015   #17
-
0
-

ingiraxo:

díky. Tak to asi pracuje neomezeně na libovolný počet cifer, viď? Mě konkrétně stačili 4 cifry, takže viz před tebou moje řešení, ještě se to dá udělat tak, že to nejdříve posunu doleva o dvě cifry a pak použuju masku zprava kratší o dvě cifry.

Nahlásit jako SPAM
IP: 78.45.199.–
ingiraxo+15
Grafoman
14. 3. 2015   #18
-
0
-

#17 oxidián
ne, též to pracuje na 4 cifry, číslo int to vždy převede do binaru o 8 bitech, takže velikost vstupního čísla nijak nemění rychlost převodu (cyklus se vždy vykoná 8x pro celý vypočet)

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
oxidián0
Grafoman
14. 3. 2015   #19
-
0
-

Tak jsem se to jal otestovat a změřit. Vytvořil jsem smyčku 4000x4000 cyklů aby byl vidět rozdíl. Časovač resetován těsně před cyklem a po cyklu ukončen.

PRVNÍ TESTY OBSAHUJÍ CHYBU:

Toto je můj kód

    uint32_t n,m;
    n=0; m=4000*4000;
    uint16_t k,kk,kkk,kkkk;
    unsigned char a,b,c,d;
    k=kk=kkk=kkkk = 75;

    for (;n<m;n++){
        a = k & ~(0b11111100);
        b = (kk & ~(0b11110011)) >> 2 ;
        c = (kkk & ~(0b11001111)) >> 4;
        d = (kkkk & ~(0b00111111)) >> 6;
    }

čas: 0.053548s luxus...

Následuje kód od KIIV:

uint32_t neco = 75;
char vystup[17] = {0};
char * pv = vystup+16;
for (;n<m;n++){
while (neco > 0)
{ *(--pv) = '0' + (neco&3); neco >>= 2; }
}

0.027899s

OPRAVENÉ TESTY:

Teď ta novější funkce od ingiraxo:

    for (;n<m;n++){
        homework(75, r); // 1023    
        }

0.689556s

Můj kód:

    for (;n<m;n++){
        k=kk=kkk=kkkk = 75;
        a = k & ~(0b11111100);
        b = (kk & ~(0b11110011)) >> 2 ;
        c = (kkk & ~(0b11001111)) >> 4;
        d = (kkkk & ~(0b00111111)) >> 6;
    }

0.187825s

A ještě jednou KIIVův kód taky opraveno:

    char vystup[17] = {0};
    char * pv;
    uint32_t neco;
    for (;n<m;n++){
        neco = 75;
        pv = vystup+16;
        while (neco > 0) {
            *(--pv) = '0' + (neco&3);
            neco >>= 2;
            }
    }

0.203267s

Vyhrál jsem pánové :-)

Edit:

Ještě jsem zkusil toto:

    for (;n<m;n++){
        k=kk=kkk=kkkk = 75;
        a = k & ~(0b11111100);
        b = ((kk >> 2) & ~(0b111100)) ;
        c = ((kkk >> 4) & ~(0b1100)) ;
        d = ((kkkk >> 6) & ~(0b00)) ;
    }


A výsledek je pomalejší: 0.196561s

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
14. 3. 2015   #20
-
+1
-
Zajímavé

#19 oxidián
proc ti nestaci:

    for (;n<m;n++){
        k = 75;
        a = k & 0b11;
        b = (k & 0b1100)) >> 2 ;
        c = (k & 0b110000)) >> 4;
        d = (k & 0b11000000)) >> 6;
    }

kazdopadne ja k tomu jeste pripocitavam tu '0' a zvladnu klidne cely 32b cislo a tak...

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
14. 3. 2015   #21
-
0
-

KIIV:

Tak to je výhoda.

Ještě zkouším šestnáctkovou soustavu:

k=kk=kkk=kkkk = 415;
a = k & ~(0b111111110000);
b = (kk & ~(0b111100001111)) >> 4 ;
c = (kkk & ~(0b000011111111)) >> 8;
int c_ = 15; n = (uint32_t) a; printf("%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }
c_ = 15; n = (uint32_t) b; printf("%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }
c_ = 15; n = (uint32_t) c; printf("%d\n",n); for (; c_ >= 0; c_--) { k = n >> c_; if (k & 1) printf("1"); else printf("0"); }


nefunguje mi to ale, někde je chyba binární výsledky mi končí na 0b11119, 0b10011 a 0b0001

má vyjít
 

4       1   5
0100 0001 0101
Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
14. 3. 2015   #22
-
0
-

VÝTĚZNÝ KÓD:

 0.044624s!!! Mazec!

for (;n<m;n++){
   k = 75;
   a = k & 0b11;
   b = (k & 0b1100) >> 2 ;
   c = (k & 0b110000) >> 4;
   d = (k & 0b11000000) >> 6;
}

Dík KIIV

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
14. 3. 2015   #23
-
0
-

jen nezapomen, ze ti to optimalizace muze uplne vyhodit, kdyz to pak nepouzijes (ci si to rekne, ze je to furt stejny, tak to spocita v jednom kole a necha ti to vysledek)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
14. 3. 2015   #24
-
0
-

Co je "to"? A co mi může vyhodit? A co myslíš tím "vyhodit"? A co že má být furt stejný? Nepochopil jsem ani jednu větu.

Proč vlastně ta maska vždycky musí začínat dvěma jedničkama 0b11? V kódu cos napsal nakonec.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
15. 3. 2015   #25
-
0
-

když tam dám rand() tak to trvá déle cca 0.2, ale to může být voláním té funkce.

Když tam dám toto: k = (k & 0b1) ? 75 : 65 ; tak to trvá 0.049s

Když tam dám toto: k = (k & 0b1) ? 175 : 165 ; tak to trvá 0.0496s

Rozdíly nejsou velké pokud ze smyčky nevoláš nějakou funkci.

Nahlásit jako SPAM
IP: 78.45.199.–
ingiraxo+15
Grafoman
15. 3. 2015   #26
-
0
-

já mám dojem, že to zbytečně moc řešíš. proč prostě nepoužiješ to co napsal kiiv? Pro tvůj případ, kdy to nepřevádíš přímo do binaru jako celý číslo, ale jen vypočitáváš dvojice, tak stačí ty 4 řádky s bitovým posunem.

Jestli milion iterací trva 0.04 nebo 0.2 je úplně jedno, nepoznáš v praxi při dnešním HW. A jestli je to natolik špatně optimalizovany, tak se vytvářej cache, dá se pryč kurvítko (sleep) nebo se to optimalizuje, ale někdy to úplně dobře nejde a používají se cache, tudíš i vyšší nároky na pamět.

A jestli se chceš dostat po 0.01s, tak to prostě pust na výkonějším stroji ;)

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
oxidián0
Grafoman
15. 3. 2015   #27
-
0
-

Ještě potřebuju poradit jestli správně převádím do 16ctkové soustavy:

decimal: 75
binary: 1001011

rozděleno: 0100 1011
base 16: 4 11

Edit - zkouška: (int) 75/16 = 4 a zbytek je 11. ... 4*16^1 +  11*16^0 = 411?

No to teda není jedno. Kdybych něco podobného používal na zpracování grafických operací u obrazu tak tam hrajou milisekundy velkou roli. Protože když těch operací budou desítky (různé operace, kopírování bitů, porovnávání masek, převody masek a já nevím co vše používá třeba Photoshop) tak je rozdíl jestli se ten obraz zpracuje za 0.5s nebo 2s. Když to děláš hromadně (několik desítek nebo stovek souborů) tak rozdíl může být v desítkách minut. Rozdíl jestli něco trvá 2 minuty nebo deset, 10 minut nebo 40 je dost velký. A nepotřebuju k tomu kupovat stroj za 40-90 tisíc.

"Pro tvůj případ, kdy to nepřevádíš přímo do binaru jako celý číslo, ale jen vypočitáváš dvojice, tak stačí ty 4 řádky s bitovým posunem."

Nechápu proč to píšeš? Děláš ze mě blba? Vždyť s tím bitovým posunem jsem přišel já že to tak bude nejrychlejší a vy ste pořád oponovali že to je zbytečné a že rychlejší to je přes řetězce...

Nahlásit jako SPAM
IP: 78.45.199.–
vitamin+8
Grafoman
15. 3. 2015   #28
-
0
-

#27 oxidián
Najprv si to implementuj jednoducho, ked budes mat funkcny program spust ho a zisti ktore casti kodu trvaju najdlhsie a tie casti optimalizuj. Predcasne optimalizovat je vecisinou strata casu lebo vo finalnom programe bude uzke hrdlo uplne ina cast pripadne niektore casti nakoniec ani nepouzies, cize je zbytocne ich optimaliovat.

Nahlásit jako SPAM
IP: 46.165.251.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
oxidián0
Grafoman
15. 3. 2015   #29
-
0
-

A budu ztrácet čas přepisováním? Díky, ale ne. Tys to ale asi vůbec nepochopil. Já chtěl jen 4 číslice a toho jsem dosáhl. Na tom se taky učím ty převody. Je to jednoduché a přehledné.

Časy jsem poměřoval proto, že až to budu potřebovat někde jinde vím jak dlouho to trvá a mám představu o tom co je rychlejší. Samozřejmě tu dynamickou metodu od KIIVa nezavrhuju, jen ji momentálně nepotřebuju.

Nahlásit jako SPAM
IP: 78.45.199.–
ingiraxo+15
Grafoman
15. 3. 2015   #30
-
+1
-
Zajímavé

#27 oxidián
bral jsem to tak, že ti přijde nějaký číslo a ty ho v prvním kroku potřebuješ převést do binaru a až v druhém ty dvojice projít...

nevim proč sem motáš grafický operace, tam se většinou používaj matice

souhlasim s tím co napsal vitamín.. optimalizace bývá až mezi posledními kroky, ted tomu dáš hodiny/dny a ve výsledku zjistíš, že zpomalení nastane úplně jinde a třeba ani nepůde z optimalizovat... proto jsem i psal, že to ted nemáš tolik řešit... i v praxi se optimalizace dělá až ve chvíli, kdy je potřeba, dnes se dává přednost přehlednému kódu, protože nikdy nevíš, kdo ten kód po tobě bude spravovat a taky máme vykonější stroje :)

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
oxidián0
Grafoman
15. 3. 2015   #31
-
0
-

Jenže já vám to opakuju už po sté, že toto není součást žádné složité aplikace. Je to samostatné řešení, které nemá se zbytkem jakékoliv aplikace nic společného. Chtěl jsem prostě nejjednodušší a nejefektivnější cestu. Tudíž bavit se o nějaké optimalizaci je úplně mimo mísu. Celá má aplikace tvoří asi 10 řádků kódu na kterém si testuju převod z desítkové soustavy do čtyřkové a z desítkové do šestnáctkové. Toto řešení pak mohu kdykoliv použít ve složitějším programu. Nejdůležitější ale je, že toto řešení je nejjednodušší na pochopení, a ne nějaké složité cykly které začátečníkovi třeba nic neřeknou. Je tam maska a z té masky lze odečíst jednoduše a přehledně výsledek. Celé řešení je postaveno na tom jak nejjednodušeji vysvětlit či spočítat ten převod. Že vezmeš binární ekvivalent desítkového čísla třeba 000110101011 a rozdělíš to po třech  000 110 101 011 nebo po čtyřech 0001 1010 1011. Nic víc v tom není. Není třeba dělat složité funkce, přinejmenším ne na vysvětlení základů. Nechápu co na tom nechápete.

Nahlásit jako SPAM
IP: 78.45.199.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 94 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý