Prosím, potřeboval bych program, nebo aspoň část programu, který sečte mnou zadané binární čísla. Výsledek opět bude v binární podobě. Díky za pomoc
Fórum › C / C++
Součet dvou binárních čísel
#1 Dalibor
A na co to prosímtě potřebuješ? Lidi přece počítají v desítkové soustavě. Dvojková (binární) soustava - ta je pro počítače (ty zase neumí desítkovou) a proto si to počítačové programy samy převádí a uživatele tím neobtěžují.
Prostě to zadej v desítkové, program si to sám převede do dvojkové, výsledek bude samozřejmě ve dvojkové (jak jinak) a pro tebe ho zase automaticky převede zpět do desítkové.
#5 Dalibor
Aha... no tak to jsi měl říct rovnou...
Na to ti můžu říct jen - tím, že ti to někdo napíše se to moc nenaučíš. Mnohem efektivnější je přijít na to sám.
A když něco nevíš, zeptej se strýčka...
Mimochodem, ten součet je úplně stejný - ba i jednodušší, jako ses učil na základní škole, vždyť máš jen dvě čisla...
#8 Dalibor
Aha, no ale o tom to přece je... Děláš školní úlohu - vlastně něco zbytečného - ale naučíš se u toho jak naprogramovat ten postup. Takže až budeš programovat něco užitečného, budeš vědět jak.
Nevím co vše umíš a jak, takže rada - posloupnost čísel si ulož do nějaké struktury se kterou umíš pracovat po jednotlivých položkách a cyklem projdi ty jednotlivé položky zprava doleva a hlídej si přenos - no jako na tom papíře...
#1 Dalibor
Pokud to může být C++ tak zkus tohle.
#include <bitset>
#include <string>
typedef std::string T_String;
template<size_t N> bool binarysum(const char* inNum1,const char* inNum2,T_String &outNum)
{
typedef std::bitset<N> T_BitSet;
T_String s1(inNum1);
T_String s2(inNum2);
T_BitSet n1(s1);
T_BitSet n2(s2);
T_BitSet n = (n1.to_ulong() + n2.to_ulong());
outNum = n.to_string();
return true;
}
int main()
{
T_String s;
binarysum<32>("1100100","11001000",s);
return 0;
}
Poradil by nekdo prosím jak převést to binární číslo na dekadické? Umím to pomocí tohoto vzorce
vysledek1 = vysledek1 * 2 + (binar1 - '0');
Jestli ale existuje ještě jinačí verze... Byl bych za ní vděčný. díky
Takovym zpusebem to ani nepujde pretece ti promenna. tam muze byt cislo dlouhe az 253 znaku, coz je 2^253 to do promene nedas, radsi pracuj s retezci. a pak je secti a dej do vysledneho retezce. Scitani je lehke, napr 1+1 =0 (pak jde jednicka pro prenos] atd..
nebo uplně jinak... uz jsem na to prisel... akorad to nefunguje... po vlozeni hodne velkeho retezce, to napise chybu... takze se to musi udelal jinak... a ne tim mezi prevodem... kdyby tady nekdo podrobneji popsal jak, byl bych rad. Děkuji
#24 Dalibor
dadanku, z meziprevodem na DEC to nejde, jsi limitován velikostí celočíselné proměnné, taky jsem to zkoušel a cesta tudma nevede. Správným řešením je práce s řetězcem, kde přistupuješ znak po znaku a podle hodnoty v jednotlivých prvcích a dle jednotky v řetězci součtu doplnujes hodnotu do souctu.
PS: Progtest v meznich hodnotach dosazuje opravdu dlouhe vstupni retezce, napriklad
0010010000100010010110101011000001000101000010100110001011111001001010000011111000111111011101110110000011000001001000101
co by jsi z meziprevodem na DEC nikdy nemohl zrealizovat.
Ted potrebuju nejak vyresit ten ukol... a potrebuju to napsat jako laikovi... ten text co si mi napsal, muzes napsat salounovi nebo nekomu jinemu kdo tomu rozumi... ale laikovi nebo zacatecnikovi bys to mohl prosim vysvetlit trosku polopate...
#34 Dalibor
Rada:
Načti obě vstupní čísla jako řetězce. Nachystej si výstup také jako řetězec.
Projdi cyklem postupně čísla zprava (nebo-li od poslední číslice) a zjišťuj výsledek součtu + přenos z předchozí pozice a přidávej do cílového řetězce. V případě, že dojde k přenosu i u poslední číslice delšího čísla, přidej ještě jedničku zleva.
Předpokládám, že umíš pracovat s jedotlivými znaky řetězce...
Zdravim vsechny :) Vidim ze Dalibor bude stejna fakulta co ja :D no to je fuk ja uz mam vicemene navrh scitaciho algoritmu hotovej, nicmene ... potrebuju ten retezec, kam nacitam, pred tim nez do nej zacnu nacitat, naplnit nulama ... ( jako pojistka ze jedno cislo bude kratsi nez druhy) staci to udelat
char retezec[256] = {0};
? nebo je to potreba pres treba FOR naplnit?
Zdravím, na pár řádků (a to čisté C nemám moc rád):
#include <stdio.h>
#include <stdlib.h>
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20];
printf("Zadejte prvni binarni cislo: ");
scanf("%ld", &bin1);
printf("Zadejte druhe binarni cislo: ");
scanf("%ld", &bin2);
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
printf("Soucet dvou binarnich cisel je: ");
while (i >= 0) printf("%d", sum[i--]);
system("PAUSE");
return 0;
}
Proč nad tím tak bádáte? Stačí se trochu zamyslet... To zbytečné uzávorkování tam být nemusí, pro přehlednost jsem raději doplnil. V C++ to jde napsat i do pěti řádků. :-)
#51 JoDiK
On si do long intu ulozil cislo a predpokladal ze uzivatel zadal binarne cislo. Takze nie len ze ten program nezvladne viac bitove cisla ktore su vecsie ako long int, ale ten program nezvladne ani cisla ktore sa zmestia do longu :)
Jak byste vyjádřili podmínku pro nesprávný vstup u tohoto kódu, co napsal RePRO? Mám totiž podobný, ale vzhledem k DU ho tady nebudu psát. Myslím podmínku pro to, aby při napsání jiného vstupu než jedniček a nul zahlásil program chybu... Zkoušel jsem kombinovat if závorky, ale bohužel mi to nešlo... Děkuji
#include <stdio.h>
#include <stdlib.h>
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20];
printf("Zadejte prvni binarni cislo: ");
scanf("%ld", &bin1);
printf("Zadejte druhe binarni cislo: ");
scanf("%ld", &bin2);
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
printf("Soucet dvou binarnich cisel je: ");
while (i >= 0) printf("%d", sum[i--]);
system("PAUSE");
return 0;
}
#54 Matsn
Nacitas vstup ako text a potom v cykle skontrolujes ci sa tam nenachadzju ine znaky ako '0' a '1'. Potom mozes pouzit napr. sscanf() na nacitanie znaku z retazca (toho skontrolovaneho).
char retazec[50];
scanf("%49s", retazec);
for(char* str = retazec; *str != '\0'; ++str)
if(*str != '0' && *str != '1')exit(EXIT_FAILURE);
int i;
sscanf(retazec, "%d", &i);
(nekompiloval som to, mozu tam byt dake chyby, ale princip snad pochopis)
#57 vitamin
Počkej, já si vložil long int cislo1 a pak cislo2, abych oddělil dvě čísla mezerou, které pak sečte v binárních hodnotách, mám to přeměnit na char cislo1 a char cislo2 a vypsat ify, které si napsal pro ně?
Máš mail, prosím tě? Ukázal bych ti, co jsem vybástlil...Protože mi to nefunguje :(
Nauc sa pouzivat stavove automaty a ziaden sialeny format nebude pre teba problem :
Tu mas kod ktory otestuje format vstupu ( dekadicke_cislo , dekadicke_cislo ). Tebe staci upravyt program tak aby fungoval len pre znaky '0' a '1'
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
typedef enum {true=1, false=0} bool;
bool osetri(const char* retazec){
typedef enum {Begin, Cislo1, Medzera, Ciarka, Cislo2, End}state_t;
state_t stav = Begin; //pociatocny stav
const char* cislo1 = NULL; //zaciatok cisla1 (toto mozes na konci funkcie nacitat ako cislo pomocou sscanf())
const char* cislo2 = NULL; //zaciatok cisla2 ( - || - )
//prejde postupne vsetky znaky retazca
for(const char* str = retazec; *str != '\0'; ++str)
switch(stav){
case Begin: //pri cisle sa prepne do stavu Cislo1, pri prazdnom znaku ostane v stave Begin, pri ostatnych znakoch vrati false
if(isdigit(*str)){
stav = Cislo1;
cislo1 = str;
}
else if(!isspace(*str))return false;
break;
case Cislo1: //pri prazdnom znaku sa prepne do stavu Medzera, pri ciarke sa prepne do stavu Ciarka, pri Cisle ostane v stave Cislo1, pri inom znaku vrati chybu
if(isspace(*str))stav = Medzera;
else if(*str == ',')stav = Ciarka;
else if(!isdigit(*str))return false;
break;
case Medzera: //pri ciarke sa prepne do stavu Ciarka, pri prazdnom znaku ostane v stave Medzera, inak vrati chybu
if(*str == ',')stav = Ciarka;
else if(!isspace(*str))return false;
break;
case Ciarka: //prazdne znaky ignoruje (ostane v stave Ciarka), pri prichode cisla prejde do stavu Cislo2, inak vrati chybu
if(isdigit(*str)){
stav = Cislo2;
cislo2 = str;
}
else if(!isspace(*str))return false;
break;
case Cislo2: //po prazdnom znaku prejde do stavu End, pri cisle ostane v stave Cislo2, inak vrati chybu
if(isspace(*str))stav = End;
else if(!isdigit(*str))return false;
break;
case End: //ignoruje prazdne znaky, inak vrati chybu
if(!isspace(*str))return false;
break;
}
if(stav == Cislo2 || stav == End)return true; //ak sa po prejdeni celeho retazca rovna stav Cislo2 alebo End, tak vstupny retazec vyhovuje ziadanemu formatu
return false; //vstup nevyhovuje ziadanemu formatu
}
int main(){
char retazec[200] = "";
while(true){
if(!fgets(retazec, 200, stdin))return EXIT_FAILURE;
if(osetri(retazec) == true)puts("vstup je v spravnom formate\n");
else puts("vstup je chybny");
}
return EXIT_SUCCESS;
}
Co tento kód?
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20];
cout << "Zadejte dve binarni cisla:\n";
cin >> bin1 >> bin2;
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
cout << "Soucet: ";
while (i >= 0) printf("%d", sum[i--]);
char reakce;
cin >> reakce;
return 0;
}
Další možné řešení, které ne a ne splňovat kritéria
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20], number = 0;
cout << "Zadejte dve binarni cisla:\n";
cin >> bin1 >> bin2;
int dv;
number = bin1;
while(number!=0)
{
dv=number%10;
if(dv>1)
cout << "Neni binarni";
number=number/10;
}
number = bin2;
while(number!=0)
{
dv=number%10;
if(dv>1)
cout << "Neni binarni";
number=number/10;
}
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
cout << "Soucet: ";
while (i >= 0) printf("%d", sum[i--]);
char reakce;
cin >> reakce;
return 0;
}
if( (bin1 % 10 != 0) && (bin1 % 10) != 1){
cout << "cislo 1 nie je binarne" << endl;
exit(EXIT_FAILURE);
}
if( (bin2 % 10 != 0) && (bin2 % 10) != 1){
cout << "cislo 2 nie je binarne" << endl;
exit(EXIT_FAILURE);
}
Nechci se nějak dotknout vitamina, to co napsal pomocí stavového automatu je východisko a možné řešení, ale pro takto jednoduchý příklad stačí něco takového (zatím jenom hodně pseudo a z hlavy):
bool check(long int number, int search_1, int search_2)
{
while (number > 0)
{
int digit = number % 10;
number = number / 10;
if (digit != search_1 && digit != search_2) return false;
}
return true;
}
Poté tu funkci zavoláme:
std::cout << check(10101010, 1, 0) << " \n";
Takže teď to udělá to, že 10101010 to vezme, ale 10101012 to nevezme. Problém nastane, pokud zkusíme otestovat 00101010 (na začátku je nula, to pak reprezentuje oktanové číslo). To budu muset ještě promyslet. Je to vlastně to, co napsal vitamin výše... Zkoušel jsi to vitamine pro vstup 01010101?
Tak funguje, takže chválím nakonec vitamina za pěkné řešení!
Takže jenom zkrátím pro úplnost:
bool check(int long number)
{
return ((number % 10 != 0) && (number % 10) != 1);
}
Ach bože, nejede to. Když tam zadám například písmena, objeví se nějaký nedobrý ascii součet. Napište mi prosím celý kód, chci se toho jen rychle zbavit už, je to poslední úloha a nad moje síly :( DĚKUJI :(
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20];
cout << "Zadejte dve binarni cisla:\n";
cin >> bin1 >> bin2;
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
if( (bin1 % 10 != 0) && (bin1 % 10) != 1){
cout << "cislo 1 nie je binarne" << endl;
}
if( (bin2 % 10 != 0) && (bin2 % 10) != 1){
cout << "cislo 2 nie je binarne" << endl;
}
cout << "Soucet: ";
while (i >= 0) printf("%d", sum[i--]);
char reakce;
cin >> reakce;
return 0;
}
#68 Aliande
cin >> bin1 >> bin2;
tento kod ocakava ze zadas len cisla, ak zadas nieco ine, tak sa nastavy v streame cin failbit ktory mozes zistit pomocou funkcie cin.fail(). Ak je nastaveny failbit (alebo badbit) tak sa neda stream pouzit a musis ho "resetnut" pomocou cin.clear().
Takhle je to i s tím ošetřením, jde to?
#include <cstdlib>
#include <iostream>
using namespace std;
bool check(int long number)
{
return ((number % 10 != 0) && (number % 10) != 1);
}
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20];
cout << "Zadejte prvni bin. cislo: ";
cin >> bin1;
while( check(bin1) )
{
cout << "Spatny vstup - zadejte znovu: ";
cin >> bin1;
}
cout << "Zadejte druhe bin. cislo: ";
cin >> bin2;
while( check(bin2) )
{
cout << "Spatny vstup - zadejte znovu: ";
cin >> bin2;
}
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
printf("Soucet dvou binarnich cisel je: ");
while (i >= 0) printf("%d", sum[i--]);
system("PAUSE");
return 0;
}
Takhle je to neprofesionálně, v C++ by se to mělo dělat pomocí cin.fail a cin.clear (jak píše vitamin). Ale každopádně toto můžeš taky poslat.
Upravil jsem to na tohle. Bohužel pořád ty chyby... Když zadám písmena, vyhodí to nesmyslnou hodnotu. Když zadám nějaká čísla 565545 apod nepíše to nic... Ale sčítání funguje...Bihužel pořád se bavíme o těch chybách
#include <cstdlib>
#include <iostream>
using namespace std;
bool check(int long number)
{
return ((number % 10 != 0) && (number % 10) != 1);
}
int main()
{
long int bin1, bin2;
int i = 0, zbytek = 0, sum[20];
cout << "Zadejte prvni bin. cislo: ";
cin >> bin1 >> bin2;
while( check(bin1) )
{
cout << "Nespravny vstup.";
}
while( check(bin2) )
{
cout << "Nespravny vstup.";
}
while ((bin1 != 0) || (bin2 != 0))
{
sum[i++] = ((bin1 % 10) + (bin2 % 10) + zbytek) % 2;
zbytek = ((bin1 % 10) + (bin2 % 10) + zbytek) / 2;
bin1 = bin1/10;
bin2 = bin2/10;
}
if (zbytek != 0) sum[i++] = zbytek;
--i;
printf("Soucet dvou binarnich cisel je: ");
while (i >= 0) printf("%d", sum[i--]);
char reakce;
cin >> reakce;
return 0;
}
Výstup má totiž vypadat takto - což bohužel opravdu nevím jak udělat :(
Zadejte dve binarni cisla:
10101 101001
Soucet: 111110
Zadejte dve binarni cisla:
1111100 100
Soucet: 10000000
Zadejte dve binarni cisla:
101 101
Soucet: 1010
Zadejte dve binarni cisla:
11111 111
Soucet: 100110
Zadejte dve binarni cisla:
001 000001
Soucet: 10
Zadejte dve binarni cisla:
10020 1001a0
Nespravny vstup.
Zadejte dve binarni cisla:
abraka1dabra0 1fuj0tajksl1
Nespravny vstup.
Tu mas kod, pouzil som funkciu na prevod stringu obsahujuceho cislo na uint64_t (to je vlastne unsigned long, premenuj si to ak chces), funkcia pracuje s bazami 1-10 a testuje pretecenie (ak nepotrebujes testovat pretecenie tak si odtial odstran polku kodu a ak potrebujes len binarne cisla tak zmaz aj template cast a 'base' nahrad 2) .
Program nacita dva stringy, skonvertuje ich na cislo a potom zrata cisla a naspet ich skonvertuje na string.
#include <iostream>
#include <string>
#include <limits>
#include <cstdint>
using namespace std;
template <unsigned short base>
bool str2uint(uint64_t &num, const string& str){
static_assert( 0 < base && base <= 10, "zla baza" );
num = 0;
uint64_t vaha = 1; //vaha ktorou sa nasobi nacitany znak(cislo)
bool overflow = false; //pretecenie (pouziva sa ked pretecie vaha, ak su 0-ly pred cislom tak pretecena vaha nevadi)
//reverzne spracovanie vstupneho stringu
for(auto i = str.rbegin(); i != str.rend(); ++i){
uint8_t c = (*i - '0');
if(c >= base){ //chybny znak v retazci
num = 0;
return false;
}
uint64_t tmp_num;
if(c && overflow){
num = std::numeric_limits<uint64_t>::max();
return false; //pretecenie
}
tmp_num = num;
tmp_num += c * vaha;
if(tmp_num < num){
num = std::numeric_limits<uint64_t>::max();
return false; //pretecenie
}
else num = tmp_num;
if(vaha > vaha * base)overflow = true; //pretecenie vahy
vaha *= base;
}
return true;
}
string uint2bin_str(uint64_t num){
string str;
uint64_t x = 0;
uint64_t y = 1;
for(; (x < y) && (y <= num); (x = y), (y *= 2))
str += (num & y)?'1':'0';
return string(str.rbegin(), str.rend());
}
int main(){
uint64_t bin1, bin2;
string str_bin1, str_bin2;
while(true){
cout << "Zadejte dve binarni cisla:" << endl;
cin >> str_bin1 >> str_bin2;
if(!str2uint<2>(bin1, str_bin1) || !str2uint<2>(bin2, str_bin2)){
cerr << "Nespravny vstup." << endl << endl;
continue;
}
cout << "Soucet: " << uint2bin_str(bin1 + bin2) << endl << endl; //pri scitani moze nastat pretecenie
}
return EXIT_SUCCESS;
}
edit: velku cast programu som pisal uz davno,preto tam je zopar zbitocnosti (pre teba).
skrat tu vrchnu funkciu na:
bool str2uint(uint64_t &num, const string& str){
num = 0;
uint64_t vaha = 1;
for(auto i = str.rbegin(); i != str.rend(); ++i){
uint8_t c = (*i - '0');
if(c >= 2)return false;
num += c * vaha;
vaha *= 2;
}
return true;
}
a zmaz <2> v maine
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Součet dvou binárních čísel — založil thifferx
Součet dvou binárních čísel — založil Eva
Součet binárních čísel — založil Divisor
Spojový seznam - součet dvou celých čísel — založil ardno03
Sčítání Binárních čísel — založil Petr
Moderátoři diskuze