suma binarna

0

Witam,

Moje zadanie to napisać program który liczy sumę dwóch liczb binarnych i wyświetlą ją - bez spacji (niżej dokładne polecenie), no i napisałem programik który na ideone działa prawidłowo, jednak moja uczelniana sprawdzarka wyświetla błąd uruchomienia, nie bardzo wiem o co chodzi bo spr. nie zwraca złej odp. tylko błąd uruchomienia zaś kompilator online nie. Byłbym wdzięczny jak by ktoś rzucił na to oko.

treść zadania:
Dane są dwie liczby, zapisane w postaci binarnej. Oblicz ich sumę, a wynik podaj również w postaci binarnej.

Wejście

W pierwszej linii wejścia znajduje się jedna liczba całkowita d (1 <= d <= 100), która oznacza liczbę zestawów dnych.
Każdy zestaw z czterech linii. W pierwszej znajduje się liczba bitów n (1<=n<=10000), na których zapisana jest pierwsza liczba.
W drugiej znajduje się n cyfr: zer lub jedynek, które oznaczają ową liczbę.
W trzeciej znajduje się liczba bitów m (1<=n<=10000), na których zapisana jest druga liczba.
W czwartej znajduje się m cyfr: zer lub jedynek, które oznaczają ową liczbę.
W zapisie liczb nie ma zer wiodących, tzn. liczba zawsze na pierwszym miejscu posiada 1, chyba, że liczba jest zerem (1 bit równy 0).

Wyjście

Na wyjściu należy dla każdego zestawu danych wypisać ciąg zer i jedynek (bez spacji), który odpowiada zapisowi binarnemu liczbie będącej sumą liczb podanych na wejściu.

Przykład

Wejście:
2
4
1 0 0 1
2
1 1
4
1 1 1 1
6
1 1 1 1 1 1

Wyjście:
1100
1001110

#include <cstdlib>
#include <iostream>

using namespace std;

int potega(int a,int b)
{
    if(b==0) return 1;
    int temp=1;
    for(int j=0; j<b; ++j)
    {
            temp=temp*a;
    }
    return temp;
}

int main()
{
    int lt=0;
    cin>>lt;
    for(int p=0; p<lt; ++p)
    {
            int n=0,m=0,first_n=0,second_n=0,sum=0,c=0;
            int *temp=new int[10000];
                cin>>n;
                       int *tab1 = new int[n];
                           for(int j=0; j<n; ++j) cin>>tab1[j];
                                   for(int i=(n-1),k=0; i>=0; --i,++k)
                                   {
                                           if(tab1[i]==1) first_n=first_n+potega(2,k);
                                   }
                cin>>m;
                       int *tab2 = new int[m];
                           for(int q=0; q<m; ++q) cin>>tab2[q];
                                   for(int w=(m-1),e=0; w>=0; --w,++e)
                                   {
                                           if(tab2[w]==1) second_n=second_n+potega(2,e);
                                   }
                                           sum=first_n+second_n;
                                                                while(true)
                                                                {
                                                                 if(sum==1) {temp[c]=1; break;}
                                                                 if(sum%2==0){temp[c]=0;sum=sum/2;}
                                                                                                 else {temp[c]=1;sum=(sum-1)/2;}
                                                                 ++c;
                                                                }
                for(int o=c; o>=0; --o)
                {
                        cout<<temp[o];
                }
                delete[] tab1;
                delete[] tab2;
                delete[] temp;
    }
    return 0;
}
0

Hmmm, a wiesz jaki to jest błąd wykonania?
Ogólnie całość jest źle, musisz zmienić koncepcję. W założeniach zadania masz, że liczba może się składać nawet z 10000 bitów - nie masz najmniejszych szans zmieścić tego w jakimkolwiek prostym typie, a już na pewno nie int, który pomieści Ci 31 bitów plus znak. unsigned long long int pomieści Ci 64bit'y i to jest max co możesz wyciągnąć z typów prostych.

Może to wyglądać tak:
wczytać obie liczby jako tablice bool(lepiej jako vector) i zaimplementować najzwyklejsze dodawanie pisemne. Na szybko, więc pewnie nie do końca poprawnie i na pewno można lepiej

vector<bool> * dodaj(const vector<bool> *first, const vector<bool> *second)
{
	if(first->size() < second->size())
	{
		const vector<bool> *tmp = first;
		first = second;
		second = tmp;
	}

	int i = first->size() - 1;
	int j = second->size() - 1;
	vector<bool> *ret = new vector<bool>(first->begin(), first->end());
	bool overflow = false;
	bool tmp;

	while(j >= 0)
	{
		tmp = (*first)[i] ^ (*second)[j]; //xor - 1 na danej pozycji będzie tylko wtedy gdy tylko na jednej jest 1
		tmp =  tmp ^ overflow; //j.w. ale tu bierzemy pod uwagę przeniesienie

		if(((*first)[i] && (*second)[j]) || (((*first)[i] ^ (*second)[j]) && overflow))
			overflow = true;
		else
			overflow = false;

		(*ret)[i] = tmp;

		i--;
		j--;
	}

	if(overflow)
		ret->insert(ret->begin(), true);

	return ret;
}
0

Osobiście zrobiłbym to tak:

  1. Olał liczbę bitów.
  2. Wczytał bity do std::stringa bity.
  3. Wywołał strtol z argumentami bity.c_str(), NULL, 2.
  4. Powtórzył.
  5. Dodał long int'y.
  6. ( przekonwertował i ) Wypisał za pomocą itoa.
  7. Zapętlił.

W każdym razie:
http://www.cplusplus.com/reference/clibrary/cstdlib/strtol/
http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/

0

@up: i źle zrobił całe zadanie. Myślisz, że 10k bitów zapiszesz w long int? To jaki masz kompilator, który ma tak wielkiego long int'a?

0

no o.k @byku_guzio, wykorzystując twoją funkcję dodaj(), tworze tab1, tab2 typu bool, gdzie upchnę bity(tutaj wartości bool) danej liczby, chyba mam braki w wiedzy na temat klasy vector bo coś metoda push_back nie chce mi zadziałać a powinna dla bool'a, z tego co doczytałem na różnych stronach to powinienem napisać: push_back(new bool(element1)) albo push_back(new tab1(element1)) lub wszystko źle, szczerze to widzę, że robię coś źle ale nie wiem co...

#include <cstdlib>
#include <iostream>
#include <vector>
 
using namespace std;
 
    vector<bool> * dodaj(const vector<bool> *first, const vector<bool> *second)
    {
        if(first->size() < second->size())
        {
                const vector<bool> *tmp = first;
                first = second;
                second = tmp;
        }
        int i = first->size() - 1;
        int j = second->size() - 1;
        vector<bool> *ret = new vector<bool>(first->begin(), first->end());
        bool overflow = false;
        bool tmp;
        while(j >= 0)
        {
                tmp = (*first)[i] ^ (*second)[j]; //xor - 1 na danej pozycji będzie tylko wtedy gdy tylko na jednej jest 1
                tmp =  tmp ^ overflow; //j.w. ale tu bierzemy pod uwagę przeniesienie
                if(((*first)[i] && (*second)[j]) || (((*first)[i] ^ (*second)[j]) && overflow))
                        overflow = true;
                else
                        overflow = false;
                (*ret)[i] = tmp;
                i--;
                j--;
        }
        if(overflow)
                ret->insert(ret->begin(), true);
        return ret;
    } 
 
int main()
{
    int n=0,m=0;
    bool element1,element2;
vector<bool> *tab1;
cin >> n;
for( int i=0; i<n; ++i )
{
   cin >> element1;
   tab1->push_back(element1);
}
vector<bool> *tab2;
cin >> m;
for( int e=0; e<m; ++e )
{
   cin >> element2;
   tab2->push_back(element2);
}
cout<<dodaj(tab1,tab2);
system("PAUSE");
return 1;
}
0

No robisz bardzo źle. Tworzysz wskaźnik do vector<bool> i nigdzie dla niego nie alokujesz pamięci. W ogóle te wskaźniki nie są tu potrzebne.
cout << dodaj(...); też raczej nie zadziała
Dodatkowo musisz pamiętać o zwolnieniu pamięci jak już wykorzystasz to co funkcja dodaj zwróci.

1 użytkowników online, w tym zalogowanych: 0, gości: 1