Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Czemu mój kod nie działa poprawnie dla cyfry 9?

Ostatnio zmodyfikowano 2014-10-12 17:27
Autor Wiadomość
olokotampus
Temat założony przez niniejszego użytkownika
Czemu mój kod nie działa poprawnie dla cyfry 9?
» 2014-10-11 14:48:15
Napisałem program do mnożenia dwóch liczb o dowolnej długości przez siebie (kwadrat) i wszystko działa dobrze, jeśli tylko w liczbie nie ma dziewiątek. Jeśli jest dziewiątka, to program nie przesuwa części dziesiętnej do następnej komórki wyniku: 9x9 = 81, 8 znika, z 1 wszystko ok. Męczę się z tym od paru dni, analizuję krok po kroku i dalej nie widzę błędu.

Kod:
C/C++
/* Zbiku, komentuj kazda jebana linijke, nawet ta z iteracja petli, bo na 100% za pol roku
* zapomnisz co pisales, gdzie i do czego mialo sluzyc, i skonczy sie tak, ze oblejesz swoj
* wlasny program. D: Stres potrafi zdzialac cuda... =__="
*/

#include <iostream>

using namespace std;

// implementacja mnozenia pisemnego (nieograniczona ilosc cyfr, trololo~)
char * kwadratPisemnie( char * liczba, int liczbaCyfr )
{
    char * wynik = new char[ liczbaCyfr * 2 ];
    //zerowanie tablicy (losowe smieci z RAMu, nagie dziewoje...)
    for( int i = 0; i <( liczbaCyfr * 2 ); i++ )
         wynik[ i ] = 0;
    // **wlasciwe mnozenie pisemne**
    // 1) jak pomnozysz 3 razy 8, to ci wyjdzie 24
    // 2) 2 nie mozesz zapisac w tej samej komorce co 4, wiec 2 przesuwasz i zapisujesz tylko 4
    int przesuniecie;
    // wskazuje pozycje (wow, serio?! O___O" XD) cyfry w liczbie, do ktorej dodajemy w aktualnym kroku
    int wskaznikPozycji;
    // licznik dekrementacji wskaznika pozycji - o ile dekrementowac wskaznik w stosunku do wartosci stalej (liczby cyfr)
    int licznikDekrWskPoz = 0;
    for( int i = liczbaCyfr - 1; i >= 0; i-- )
    {
        przesuniecie = 0;
        wskaznikPozycji =( liczbaCyfr * 2 ) - 1 - licznikDekrWskPoz;
        for( int j = liczbaCyfr - 1; j >= 0; j-- )
        {
            //cout << (liczba[i]*liczba[j]) / 10 << ",";
            //cout << (liczba[i]*liczba[j]) % 10 + przesuniecie << " ";
            //cout << wskaznikPozycji << " ";
            //cout << wynik[wskaznikPozycji] + 0;
            //cout << "ps:" << przesuniecie << " ";
            wynik[ wskaznikPozycji ] +=( liczba[ i ] * liczba[ j ] ) % 10 + przesuniecie;
            przesuniecie =( liczba[ i ] * liczba[ j ] ) / 10;
            //cout << "p0:" << przesuniecie << " ";
            if( wynik[ wskaznikPozycji ] > 9 )
            {
                przesuniecie +=( wynik[ wskaznikPozycji ] / 10 );
                //cout << "p+:" << przesuniecie << " ";
                wynik[ wskaznikPozycji ] -=( wynik[ wskaznikPozycji ] / 10 ) * 10;
            }
            wskaznikPozycji--;
        }
        licznikDekrWskPoz++;
        //cout << endl;
    }
    //for (int i=0 ; i<liczbaCyfr ; i++)
    //cout << wynik[i] + 0 << " ";
   
    return wynik;
}

int main()
{
   
    char test1_liczba[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int test1_liczbaCyfr = 8;
    char test2_liczba[] = { 3, 7, 2, 0, 0, 4, 1, 2, 5, 7, 8, 8, 8, 1, 2, 0, 2 };
    int test2_liczbaCyfr = 17;
    char test3_liczba[] = { 1, 2, 3, 4, 9, 5, 6 };
    int test3_liczbaCyfr = 7;
    char * wynikMnozenia = kwadratPisemnie( test1_liczba, test1_liczbaCyfr );
    cout << "12345678 do kwadratu to ";
    for( int i = 0; i < test1_liczbaCyfr * 2; i++ )
         cout << wynikMnozenia[ i ] + 0;
   
    cout << endl;
    wynikMnozenia = kwadratPisemnie( test2_liczba, test2_liczbaCyfr );
    cout << "37200412578881202 do kwadratu to ";
    for( int i = 0; i < test2_liczbaCyfr * 2; i++ )
         cout << wynikMnozenia[ i ] + 0;
   
    cout << endl;
    wynikMnozenia = kwadratPisemnie( test3_liczba, test3_liczbaCyfr );
    cout << "1234956 do kwadratu to ";
    for( int i = 0; i < test3_liczbaCyfr * 2; i++ )
         cout << wynikMnozenia[ i ] + 0;
   
    cout << endl;
    return 0;
}
P-118252
stryku
» 2014-10-11 15:13:07
Próbowałeś debugować?
P-118255
SocrateZ
» 2014-10-11 15:41:32
Nie wiem o co ci chodzi z tą 9.
Twój kod działa poprawnie dla 15 * 15, ale juz nie dla 25 * 25. Zapominasz o pozostałym przesunięciu po mnożeniu.

bezpośrednio przed
licznikDekrWskPoz++;
 dodaj to:
C/C++
if( przesuniecie > 0 )
     wynik[ wskaznikPozycji ] += przesuniecie;
Dlaczego tak?
Przeanalizujmy:


15*15
-----
5*5 = 25 - 2 dalej
1*5 = 5 + (2 reszty) = 7
1*5 = 5
1*1 = 1 + (0 reszty) = 1
-----
   75
+ 15
-----
= 225
To działa

Teraz:
25*25
----
5*5 = 25 - 2 dalej
2*5 = 10 + (2 reszty) = 12 (wycina jedynke, zostawia 2) <- Tutaj masz błąd
2*5 = 10 - 1 dalej
2*2 = 4 + (1 reszty) = 5
----
   25
+ 50
-----
= 525
Dlaczego 525 a nie 625? Pominięta została 1 - i dlatego pomiędzy przejściem pierwszej pętli należy wstawić powyższy kod

Poza tym... komentarze pozostawiają wiele do życzenia...
P-118259
olokotampus
Temat założony przez niniejszego użytkownika
» 2014-10-12 17:27:08
Dziękuję, faktycznie zaczęło działać. :) Debugować próbowałem, ale QtCreator mi co chwila sam z siebie wywala jakieś świństwo w assemblerze przy uruchamianiu programu (nie zawsze, ale zbyt często) i nie mogłem dojść do końca debugowania. Co do komentarzy, to już od liceum się męczę z jasnymi i czytelnymi komentarzami, i chyba nie jestem do nich stworzony...
P-118362
« 1 »
  Strona 1 z 1