Forum » Programiranje » [c++] dvojisko
[c++] dvojisko
Loaded ::
Lp
Program pretvori iz desetiškega dvojiško. Samo ven mi vrže številke od zadaj. Kako jih naj obrnem? Vržem vse v polje in berem od zadaj naprej?
Hvala
int des; cin >> des; for (int i = des; i > 0; i /= 2) cout << i % 2; cout << endl;
Program pretvori iz desetiškega dvojiško. Samo ven mi vrže številke od zadaj. Kako jih naj obrnem? Vržem vse v polje in berem od zadaj naprej?
Hvala
Loadeed
bozjak ::
tako kot je gundolf rekel, to boš najlažje naredil z rekurzijo. Lahko pa seveda udejaniš svojo idejo in ostanke shraniš v tabelo, to pa izpišeš od odzadaj... A če rekurzijo že znaš, je to veliko enostavnejša rešitev.
--------resitev------
Lp
--------resitev------
#include <stdio.h> #include <stdlib.h> void rekurzija (int i) { if (i>0) rekurzija(i/2); printf("%d", i%2); } int main(int argc, char *argv[]) { int stevilo; printf("Stevilo: "); scanf("%d", &stevilo); rekurzija(stevilo); printf("\n"); system("PAUSE"); return 0; }
Lp
http://upor.blogec.si
http://bozjak.deviantart.com
http://bozjak.deviantart.com
snow ::
Po moje je AND z ustrezno masko najbolj elegantno in hitro:
[edit: zamenjal if z ?:]
int des; std::cin >> des; for(int i=0;i<32;i++) { std::cout<<((des&(1<<(31-i))) ? 1 : 0); }
[edit: zamenjal if z ?:]
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Zgodovina sprememb…
- spremenilo: snow ()
Loaded ::
Tako še ne obvladam. Zakaj mi to ne dela? Imam polje z vsemi ničlami, ki bi jih rad nadomestil od zadaj z dvojiškim številom. Ostale bi ostale ničle (8-bit zapis).
Hvala
#include <iostream> using namespace std; int main() { int des, dv; char polje[] = {'0', '0', '0', '0', '0', '0', '0', '0', '\0'}; cin >> des; for (int i = des; i > 0; i /= 2) { dv = i % 2; for (int j = 8; j > 0; j--) { dv = polje[j]; } } for (int i = 0; i < 9; i++) { cout << polje[i]; } system("pause"); return 0; }
Hvala
Loadeed
Zgodovina sprememb…
- spremenil: Loaded ()
snow ::
Meni osebno je težje vso tole deljenje, in gledanje ostanke in zapisovanje v tabelo in izpis v kontra smeri, kot pa and z bitom.
No če že hočeš, napaka je tukaj:
Ti si moraš vrednost dv zapisovat v polje in ne obratno. Za to ti ni potrebno imeti še ene zanke.
Zunaj osnovne zanke (tista kjer imaš int i=des;....), definiraj en indeks. Recimo
Nato pa vrednost znotraj zanke, po izračunu dv shranjuješ takole:
Izpis ostane isti. Ali pa v kontra smeri. Probaj :)
Pa polje bi lahko bilo dolžine 32, ker je tip int 32 biten (ponavadi na x86 c++ prevajalnikih).
No če že hočeš, napaka je tukaj:
for (int j = 8; j > 0; j--) { dv = polje[j]; }
Ti si moraš vrednost dv zapisovat v polje in ne obratno. Za to ti ni potrebno imeti še ene zanke.
Zunaj osnovne zanke (tista kjer imaš int i=des;....), definiraj en indeks. Recimo
unsigned int k=0;
Nato pa vrednost znotraj zanke, po izračunu dv shranjuješ takole:
polje[k++] = dv;
Izpis ostane isti. Ali pa v kontra smeri. Probaj :)
Pa polje bi lahko bilo dolžine 32, ker je tip int 32 biten (ponavadi na x86 c++ prevajalnikih).
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Loaded ::
Snow tvoj način je super, samo v celoti ne štekam tega:
Spremenil sem v dolzino 8, ker tako zahteva naloga.
kaj pomeni znak << med enko in 7-i? (1 << (7-i))) ? 1 : 0) ;
Spremenil sem v dolzino 8, ker tako zahteva naloga.
Loadeed
snow ::
Bit shift. Gre za premikanje (vseh) bitov v spremenljivki. V tem primeru v levo. V našem primeru nas zanima bit po bit, zato bomo uporabili en bit, ki ga premaknemo za ustrezno število mest.
Ko imamo ustrezno naštiman bit, pa izvedemo binarni and. Ta nam vrne vrednost 1 le če sta oba bita 1. Ker ima naš operand le en postavljen bit, tako testiramo ali je v vpisani cifri določen bit postavljen.
Zadnje čase se dosti ukvarjam s programiranjem mikrokontrolerjev (microchip PIC), kjer je takšno znanje manipulacije bitov s C/C++ zelo potrebno.
1<<0 = 1 (binarno: 00000001) 1<<1 = 2 (binarno: 00000010) 1<<2 = 4 (binarno: 00000100) . . . 1<<7 = 128 (binarno: 10000000)
Ko imamo ustrezno naštiman bit, pa izvedemo binarni and. Ta nam vrne vrednost 1 le če sta oba bita 1. Ker ima naš operand le en postavljen bit, tako testiramo ali je v vpisani cifri določen bit postavljen.
Zadnje čase se dosti ukvarjam s programiranjem mikrokontrolerjev (microchip PIC), kjer je takšno znanje manipulacije bitov s C/C++ zelo potrebno.
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
snow ::
Za vajo pa lahko narediš, da ne bo izpisalo začetnih 0
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Loaded ::
Naredil bi še obratno.. ne vem če je v redu.
Vneseš osembitni zapis. Moral bi narediti da z dva množi, ko pride do prve enke. Prekomplicirano. Ne vem zakaj mi noben drug način ne pade na pamet.
Snow da pretvorba iz desetiškega v dvojiški je Boolova metoda (bitni in)?
for (int j = 2; j < 8; j++) { for (int i = 1; i < 8; i *= 2) { vsota += (polje[j] * i); } } cout << 1 + vsota << endl;
Vneseš osembitni zapis. Moral bi narediti da z dva množi, ko pride do prve enke. Prekomplicirano. Ne vem zakaj mi noben drug način ne pade na pamet.
Snow da pretvorba iz desetiškega v dvojiški je Boolova metoda (bitni in)?
Loadeed
snow ::
Osembitni dvojiški v desetiško?
Jaz bi zopet delal z logičnimi operacijami. Previdevam da imaš bite v polju?
Eno spremenljivki rečeš da je 0 (vsi biti na 0). Potem pa prižigaš samo tiste bite, ki je treba (če je vrednost v polju 1). In voila.. v spremenljivki je vrednost, ki jo izpišeš (v desetiškem sistemu).
Jaz bi zopet delal z logičnimi operacijami. Previdevam da imaš bite v polju?
Eno spremenljivki rečeš da je 0 (vsi biti na 0). Potem pa prižigaš samo tiste bite, ki je treba (če je vrednost v polju 1). In voila.. v spremenljivki je vrednost, ki jo izpišeš (v desetiškem sistemu).
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Gundolf ::
Dvojna zanka nikakor ne sodi v pretvarjanje številskih sistemov. Ampak se mi zdi da tadrugo zanko notri tlačiš le zato, ker ne veš, da bi lahko obe tvoji 'zančni' spremenljivki spreminjal znotraj iste zanke:
for (int j = 1, i=2; j < 8; j++, i *= 2)
Pa tudi tako ni nujno, saj ti ni treba znotraj for stavka vseh spremenljivk definirat, preverjat in spreminjat.
for (int j = 1, i=2; j < 8; j++, i *= 2)
Pa tudi tako ni nujno, saj ti ni treba znotraj for stavka vseh spremenljivk definirat, preverjat in spreminjat.
Loaded ::
Ok. Pogruntal sem sistem bitnega in.
Snow kako pa naj prižigam bite v spremenljivki? ta spremenljivka je polje?
Snow kako pa naj prižigam bite v spremenljivki? ta spremenljivka je polje?
Loadeed
snow ::
unsigned int a=0; //vsi biti na 0 unsigned int i=0; a = a | 1<<i; //prize i-ti bit (biti gredo od 0 do 7). a|= 1<<i; //isto kot zgoraj, samo krajsi zapis
Se pravi pogledaš če v polje[i] 1, in če je postaviš i-ti bit. Za i od 0 do 7. Vrstni red pri tem seveda ni pomemben.
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Zgodovina sprememb…
- spremenilo: snow ()
Tutankhamun ::
wau prov tema lih zame .
No tak js si že neki časa razbijam glavo pa mi ne gre, tko da upam, da mi pomagate in me razsvetlite kot vedno .
Torej:
rezultat je: i = 0x00010203
Pol sm pa hotu kr v eni vrstici napisat pa mi neki ne gre
rezultat je: i = 0x00000000
Pa sm dajou še v oklepaje pa kaj js vem kaj sm še probavu pa mi ne gre.
Kaj delam narobe? In kako lahk nardim to v eni vrstici?
Pa prosim ne mi s takimi da se ne splača. Js bi rd samo vedu, k mi ne da miru...
No tak js si že neki časa razbijam glavo pa mi ne gre, tko da upam, da mi pomagate in me razsvetlite kot vedno .
Torej:
UINT i = 0; char buff[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int p = 0;
i |= *(buff + p++) << 24; i |= *(buff + p++) << 16; i |= *(buff + p++) << 8; i |= *(buff + p++);
rezultat je: i = 0x00010203
Pol sm pa hotu kr v eni vrstici napisat pa mi neki ne gre
i = *(buff + p++) << 24 | *(buff + p++) << 16 | *(buff + p++) << 8 | *(buff + p++);
rezultat je: i = 0x00000000
Pa sm dajou še v oklepaje pa kaj js vem kaj sm še probavu pa mi ne gre.
Kaj delam narobe? In kako lahk nardim to v eni vrstici?
Pa prosim ne mi s takimi da se ne splača. Js bi rd samo vedu, k mi ne da miru...
AMD Phenom QUAD 9950 Black Edition, 8GB
Quikee ::
Tutankhamun:
probaj
int a = 0;
a = a++ + a++ + a++;
printf("%d",a);
in se čudi rezultatu izpisanega a.
probaj
int a = 0;
a = a++ + a++ + a++;
printf("%d",a);
in se čudi rezultatu izpisanega a.
Tutankhamun ::
Kako nj se čudim, rezultat je 3. Js si predstavlam da se to tko izvede a = 0 + 1 + 2.
Al nevem točn kaj nj bi gledu.
Al nevem točn kaj nj bi gledu.
AMD Phenom QUAD 9950 Black Edition, 8GB
Tutankhamun ::
Bolše .
Stupid me, na neki sm pozabu .
Sm pol tko naredu
Stupid me, na neki sm pozabu .
Sm pol tko naredu
i = *(buff + p) << 24 | *(buff + p+1) << 16 | *(buff + p+2) << 8 | *(buff + p+3); p += 3;
AMD Phenom QUAD 9950 Black Edition, 8GB
Quikee ::
Ali pa tak..
i = *(buff + p) << 24 | *(buff + (p++) +1) << 16 | *(buff + (p++) + 2) << 8 | *(buff + (p++) + 3);
Tutankhamun ::
Evo prov to sm hotu. Nekak podobn sm delu, pa mi je skos neki mankal.
Hvala Quikee
Hvala Quikee
AMD Phenom QUAD 9950 Black Edition, 8GB
Loaded ::
Celotna pretvorba.
No, pa že nekaj več vemo..
#include <iostream> using namespace std; int main() { int bin[8]; unsigned int a = 0; for(int i = 0; i < 8; i++) { cin >> bin[i]; if (bin[i] == 1) { a |= 1 << (7-i); } } cout << a; system("pause"); return 0; }
No, pa že nekaj več vemo..
Loadeed
Zgodovina sprememb…
- spremenil: Loaded ()
Loaded ::
edino kar me še muči je seštevanje in dvojiški komplement. Seštevati vem in kaj je dvojiški komplement tudi vem, samo nikakor ne spraviti to skup z logičnimi operacijami.
Loadeed
snow ::
Dvojiški komplement? Mislim, da je to pretvorba iz pozitivnega v negativno število ali obratno.
Invertiraš vse bite, in prišteješ 1.
Kako invertiraš bit(e)? Uporabiš ekskluzivni ali (XOR) na bitu, ki ga želiš invertirati.
Če želiš invertirati spodnjih osem bitov narediš takole:
Invertiraš vse bite, in prišteješ 1.
Kako invertiraš bit(e)? Uporabiš ekskluzivni ali (XOR) na bitu, ki ga želiš invertirati.
Če želiš invertirati spodnjih osem bitov narediš takole:
var ^= 0xff; // 11111111 v dvojiškem, 255 v desetiškem
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins
Loaded ::
Misliš nekaj takega;
Kaj pomeni undefined reference to "ime metode" , ko hočem prevest program ?
#include <iostream> using namespace std; int main() { int vred[] = {0, 0, 0, 0, 0, 1, 0, 1}; for (int i = 0; i < 8; i++) { vred[i] ^= 1 >> (7 - i); cout << vred[i]; } system("pause"); return 0; }
Kaj pomeni undefined reference to "ime metode" , ko hočem prevest program ?
Loadeed
napsy ::
Pomeni, da prevajalnik ne najde funkcije ki jo kličeš.
"If you die, you die. But when you live you live. There is no time to waste."
Quikee ::
for (int i = 0; i < 8; i++) { vred[i] ^= 1 >> (7 - i); cout << vred[i];
hmm...
0 ^ (1 >> 7) = 0 ^ 0 = 0
0 ^ (1 >> 6) = 0 ^ 0 = 0
0 ^ (1 >> 5) = 0 ^ 0 = 0
0 ^ (1 >> 4) = 0 ^ 0 = 0
0 ^ (1 >> 3) = 0 ^ 0 = 0
1 ^ (1 >> 2) = 1 ^ 0 = 1
0 ^ (1 >> 1) = 0 ^ 0 = 0
1 ^ (1 >> 0) = 1 ^ 1 = 0
bi res rad to delal ? =)
Quikee ::
Dvojiški komplement drugače:
0000 0010 = 2 (10-desetiško)
1111 1101 = negiran 0000 0010
1111 1110 = 1111 1101 + 1 = -2 (10)
1111 1110 = -2 (10)
0000 0001 = negiran 1111 1110
0000 0010 = 0000 0001 + 1 = 2 (10)
Negiraš oz. invertiraš v C/C++ drugače lahko tudi z operatorjem ~ ampak v tem primeru se negirajo vsi biti.
0000 0010 = 2 (10-desetiško)
1111 1101 = negiran 0000 0010
1111 1110 = 1111 1101 + 1 = -2 (10)
1111 1110 = -2 (10)
0000 0001 = negiran 1111 1110
0000 0010 = 0000 0001 + 1 = 2 (10)
Negiraš oz. invertiraš v C/C++ drugače lahko tudi z operatorjem ~ ampak v tem primeru se negirajo vsi biti.
Quikee ::
int main() { int vred[] = {0, 0, 0, 0, 1, 1, 1, 1}; // 15 int i; /* // negiranje for (i = 0; i < 8; i++) { vred[i] = !vred[i]; // oz. bolj razumljivo: // if(vred[i] == 1) // vred[i] = 0; // else // vred[i] = 1; } // sestevanje int vred2[] = {0, 0, 0, 0, 0, 0, 0, 1}; int prenos = 0; for (i = 7; i >= 0; i--) { int temp = vred[i] + vred2[i] + prenos; vred[i] = !!(temp % 2); prenos = !!(temp > 1); // oz. bolj razumljivo: // if (temp % 2 == 1) // vred[i] = 1; // else // vred[i] = 0; // if (temp > 1) // prenos = 1; // else // prenos = 0; } */ // alternativa: direktno pozitivno v negativno (dvojiski komplement) oz. kombinirano negiranje in sestevanje 1 // ideja: prenos das na 1 namesto 0 na zacetku in lahko popolnoma pozabis na vred2[] = {0, 0, 0, 0, 0, 0, 0, 1}; int prenos = 1; for (i = 7; i >= 0; i--) { int temp = !vred[i] + prenos; vred[i] = !!(temp % 2); prenos = !!(temp > 1); } // 8 mestni ("8 bitni") array 1 in 0 v predznacen integer unsigned char temp = 0; int integerVrednost; for (i = 0; i < 8; i++) { temp |= vred[i] << 7-i; } integerVrednost = (int)(char) temp; cout<<integerVrednost<<endl; return 0; }
Upam, da ti bo pomagalo.
Zgodovina sprememb…
- spremenil: Quikee ()
OwcA ::
Malo sem že ven iz C++, ampak v čem je smisel !! (dvojna negacija)? Edina stvar, ki mi pade na pamet je neko obskurno pretvarjanje med tipi.
Otroška radovednost - gonilo napredka.
Gundolf ::
Po moje si zadel owca. Čeprav se mi zdi, da tako kot je napisano ni nič bolj prav, kot bi pa bilo brez negacije. Se pravi, da je notri zaradi neutemeljenega strahu pred dejstvom, da se vsak int lahko implicitno pretvori v bool.
vred[i] = !!(temp % 2);
Zgoraj pretvoriš int z dvojno negacijo v bool iste vrednosti in ga zapišeš v int, namesto da bi int zapisal direktno v int. Malo čudno.
prenos = !!(temp > 1);
Tule pa pretvoriš bool (ki je itak lahko le 1 ali 0) preko dvojne negacije v bool z isto vrednostjo (se pravi ne narediš nič) in ga nato zapišeš v int. Tule je pomoje strah, da bo (temp > 1) vrnilo true kot nek int != 1. Ampak po tej logiki bi moral obstajat tudi strah, da bo negacija vrnila true kot nek int != 1.
Če bi hotel neko ultra varnost tudi pred najbolj neumnimi prevajalniki, bi jaz napisal takole:
vred[i] = temp % 2; // same int operacije, nimaš kej zgrešit.
prenos = (temp > 1 ? 1: 0); // pameten prevajalnik bo itak poenostavil tole v operacije brez skokov - nobene kazni v hitrosti torej.
A sem zadel Quikee?
Edit:
Okay, kaj delam? Prvi stavek je valda tudi takole:
vred[i] = temp & 1;
Sem pa še pomislil, da je tole čudno, ko je temp negativen, kar pa sicer v danem primeru nikoli ne more bit, ampak takrat pa lahko dvojna negacija kaj pametnega naredi. Čeprav bi rekel, da več škode takeli hacki naredijo kot pa koristi,
vred[i] = !!(temp % 2);
Zgoraj pretvoriš int z dvojno negacijo v bool iste vrednosti in ga zapišeš v int, namesto da bi int zapisal direktno v int. Malo čudno.
prenos = !!(temp > 1);
Tule pa pretvoriš bool (ki je itak lahko le 1 ali 0) preko dvojne negacije v bool z isto vrednostjo (se pravi ne narediš nič) in ga nato zapišeš v int. Tule je pomoje strah, da bo (temp > 1) vrnilo true kot nek int != 1. Ampak po tej logiki bi moral obstajat tudi strah, da bo negacija vrnila true kot nek int != 1.
Če bi hotel neko ultra varnost tudi pred najbolj neumnimi prevajalniki, bi jaz napisal takole:
vred[i] = temp % 2; // same int operacije, nimaš kej zgrešit.
prenos = (temp > 1 ? 1: 0); // pameten prevajalnik bo itak poenostavil tole v operacije brez skokov - nobene kazni v hitrosti torej.
A sem zadel Quikee?
Edit:
Okay, kaj delam? Prvi stavek je valda tudi takole:
vred[i] = temp & 1;
Sem pa še pomislil, da je tole čudno, ko je temp negativen, kar pa sicer v danem primeru nikoli ne more bit, ampak takrat pa lahko dvojna negacija kaj pametnega naredi. Čeprav bi rekel, da več škode takeli hacki naredijo kot pa koristi,
Zgodovina sprememb…
- spremenil: Gundolf ()
Quikee ::
Dvojno negacijo bi lahko uporabil, če bi imel vrednost int, ki je večja kot 1 in bi hotel zagotovit, da se vpiše 1 (hud haklc in odvisno od kompilerja - tega ne bi nikoli uporabil v kakšnem resnem programu). Samo ko sem razmislil v obeh primerih tega ne bi bilo potrebno.
Za "vred[i] = temp & 1;" sem tudi jaz ugotovil, da bi lahko, samo komaj kasneje.
Za (temp > 1); še pa nisem našel lepega nadomestka, kot je "temp > 1 ? 1 : 0".
Tudi "int temp = !vred[i] + prenos;" mi ni všeč. Boljše mogoče "int temp = (vred[i] ^ 0x01) + prenos;"
edit: že vem "prenos = temp > 1 ? 1 : 0" lahko nadomestiš "prenos = temp >> 1"
Za "vred[i] = temp & 1;" sem tudi jaz ugotovil, da bi lahko, samo komaj kasneje.
Za (temp > 1); še pa nisem našel lepega nadomestka, kot je "temp > 1 ? 1 : 0".
Tudi "int temp = !vred[i] + prenos;" mi ni všeč. Boljše mogoče "int temp = (vred[i] ^ 0x01) + prenos;"
edit: že vem "prenos = temp > 1 ? 1 : 0" lahko nadomestiš "prenos = temp >> 1"
Zgodovina sprememb…
- spremenil: Quikee ()
Gundolf ::
> int temp = (vred[i] ^ 0x01) + prenos;
Kaj pa:
int temp = 1 - vred[i] + prenos;
Vsaj kadar želiš pretvarjati 1 v 0 in obratno je to eden izmed bolj očitnih načinov. Čeprav za moje pojme je tudi xor v redu.
Ampak nazadnje bomo ugotovil (kot da zdaj še nismo), da je najlaže najprej iz tabelce v int fliknt vse potem naredit želeno operacijo na intu in pretvorit nazaj v tabelco. Samo zakaj imam občutek, da bi prfoxi to smatrali za goljufanje? :)
Kaj pa:
int temp = 1 - vred[i] + prenos;
Vsaj kadar želiš pretvarjati 1 v 0 in obratno je to eden izmed bolj očitnih načinov. Čeprav za moje pojme je tudi xor v redu.
Ampak nazadnje bomo ugotovil (kot da zdaj še nismo), da je najlaže najprej iz tabelce v int fliknt vse potem naredit želeno operacijo na intu in pretvorit nazaj v tabelco. Samo zakaj imam občutek, da bi prfoxi to smatrali za goljufanje? :)
Zgodovina sprememb…
- odbrisalo: snow ()
Tutankhamun ::
Evo da še js pokažem kako delam dvojiški komplement.
int vred[] = {0, 0, 0, 1, 0, 1, 0, 0}; // 20 bool prva_enka_najdena = false; for(int i = 7; i >= 0; i--) { if(vred[i] && !prva_enka_najdena) { prva_enka_najdena = true; continue; } if(!prva_enka_najdena) continue; else vred[i] ^= 1; }
AMD Phenom QUAD 9950 Black Edition, 8GB
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [Java - DN] Naključna številaOddelek: Šola | 1374 (903) | nyler |
» | [C++] Brisanje znaka iz stringaOddelek: Programiranje | 995 (898) | mm1992 |
⊘ | [C#]polje znakovOddelek: Programiranje | 2399 (2227) | Ziga Dolhar |
» | Java-Izdelek-NujnoOddelek: Programiranje | 1520 (1292) | iggy |
» | [C++] urejanje nizov po velikostiOddelek: Programiranje | 2297 (2078) | Matako |