Skocz do zawartości
Maciejuś

Mnożenie Pisemne

Rekomendowane odpowiedzi

W jaki sposób zrobić program w Pascalu, który mnoży dwie dowolne liczby i wyświetla ilustrację ich pisemnego mnożenia.

Domyślam się, że najlepiej wykorzystać tablice lub stringi, ale niestety nie za bardzo umiem wykonywać operacji i na jednym i na drugim.

 

Z góry dzięki!

Edytowane przez Maciejuś

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W jaki ?? poczytaj sobie o tablicach ... dwuwymiarowych. lub o konwersji stringów na inty ...

 

słownie bym to tak zrobił

deklarujesz tablice dwuwymiarową i liczbe1 liczbe2 i inne pomocnicze

 

Wczytał liczbe1 do 2 wiersza tablicy

Wczytał liczbe2 do 3 wiersza tablicy

 

i lecisz od końca tablicy mnożysz wyrazy kolumny i z wyniku wypisujesz ostatią liczbe. pierwsząjeśli jest dajesz do wiersza 1.

 

i wyraz z kolumny1+wyraz kolumna2*wyraz kolumna3=

 

wszystko w ifa ... i gotowe ..

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Co to są "inty" i "ifa" ?

Z tego co napisałeś Vegan to niewiele kapuje.

Czytałem o tablicach i zamianie na stringi ale jest to zbyt skomplikowane dla mnie.

Cyfry tych 2 liczb trzeba wstawiać do osobnych kratek czy jak?

 

Mógłby ktoś wstawić kod takiego programu? Najlepiej się uczyć na przykładzie.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jest tu ktoś kto się zna na tym lepiej od Vegana ?

1472435[/snapback]

A na jakiej podstawie sądzisz, że Vegan się nie zna ?

Najlepiej jest wczytać dwie liczby jako ciągi znaków, potem je odwrócić i robisz tak:

dlugosca - liczba cyfr pierwszej liczby

dlugoscb - jw.

a - pierwsza liczba (tzn tablica znaków)b - jw.c - wynik działaniafor i in [0..dlugoscb]  for j in [0..dlugosca]    c[i+j] = c[i+j] + b[i] * a[j]
Teraz wszystko byłoby fajnie ale masz w tablicy cyfry w stylu 13, więc:

for i in [0..dlugosca+dlugoscb-1] {  c[i+1]  = c[i+1] + [c[i] / 10]  c[i] = c[i] modulo 10;}
I masz odwrócony wynik mnożenia w c. złożoność: O(dlugosca * dlugoscb), można szybciej ale jak chcesz tak to masz tak :D

Jeżeli chcesz wypisywać po kolei kroki, to zamiast do c[i+j] zapisuj do tymczasowej tablicy gdzie potem ją wypiszesz a jako zera wodzące wypisujesz spacje. Potem musisz oczywiście dodać wsyzstko co masz w tymczasowej tablicy do c

Edytowane przez civi

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Teraz o wiele więcej kapuje.

 

Da się to zrobić prościej - tzn. bez używania operacji na tablicach i ciągach znaków ?

Mi ktoś inny doradzał że będzie najprościej z tablicami i ciągami znaków ale jak się da prościej to prosze o wytłumaczenie.

 

Największy problem w tej chwili mam z takim podpisaniem składników mnożenia i dodawania, aby z prawej strony się ładnie wyrównały przy różnej długości liczb (normalnie są wyrównane do lewej).

Edytowane przez Maciejuś

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

heh gdzie sa moderzy - nie dosc ze regulamin gwalca to jeszcze zero zaangazowania wlasnego.

 

Maciejuś: przecytales chociaz ten kurs co ci Vegan podeslal? pamietaj ze programowanie nie polega na znajdowaniu frajerow ktorzy umieja myslec, tylko na samocdzielnym kompoonowaniu klockow.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ten kurs co mi Vegan nadesłał jest bardzo słaby. Mam lepszy na kompie.

 

Jakbyś chciał wiedzieć ayem to czytałem regulamin. Tam nie pisze, że pomoc jest niedozwolona.

 

Jeśli chodzi o ten program to chciałem zrobić to mnożenie za pomocą funkcji mod, div i pętli for i Longinta. Mój problem to to w jaki sposób ułożyć te liczby, aby ładnie się równały do prawej strony i problem ze zmiennymi przypisanymi do składników dodawania (są zależne od liczby cyfr jednej z mnożonych liczb) - myśle że najlepiej by dać do tablicy, ale też nie chce tej tablicy przypisywać ścisłej wielkości..

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Skoro tak napisałeś to pewnie skrót "int" oznacza "Integer".

Wcześniej myślałem, że to coś związanego z tablicami :razz:

 

Na razie jeszcze mam ukończonego algorytmu, więc nie będe się ośmieszał.

Pzatym nie wiem jak skopiować kod z TP do np. Notatnika.

Mam jeszcze do zrobienia wyrównanie liczb i dodawanie części składowych.

 

Znacie jakiś prostrzy sposób na wyrównanie liczb do prawej strony niż stosowanie polecenia gotoxy(x,y) , liczenia znaków w liczbach i odpowiednie wykonywanie obliczeń na nich ?

Edytowane przez Maciejuś

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

program mnozenie;uses crt;varliczbaA,LiczbaB,wynik: longint;dlgA, dlgB, dlgW, zmA, zmB, zmW: byte;beginclrscr;Writeln('Podaj pierwsza liczbe');readln(LiczbaA);clrscr;writeln('Podaj druga liczbe');readln(LiczbaB);zmA:=LiczbaA;zmB:=LiczbaB;dlgA:=0;dlgB:=0;if zmA<0 then           begin            dlgA:=dlgA + 1;            zmA:=-1*zmA;           end;if zmB<0 then           begin            dlgB:=dlgB + 1;            zmB:=-1*zmB;           end;while zmA>0 do             begin              zmA:=zmA div 10;              dlgA:=dlgA + 1;             end;while zmB>0 do             begin              zmB:=zmB div 10;              dlgB:=dlgB + 1;             end;clrscr;wynik:=LiczbaB*LiczbaA;if zmW<0 then           begin            dlgW:=dlgW + 1;            zmW:=-1*zmW;           end;while zmW>0 do             begin              zmW:=zmW div 10;              dlgW:=dlgW + 1;             end;writeln(' ');gotoxy(20,2);writeln(' ', LiczbaA);gotoxy(20,3);Writeln('*', LiczbaB);gotoxy(20,4);writeln('-------------------');gotoxy(20,5);writeln(wynik);writeln('Wcisnij ENTER aby zakonczyc program.');readln;end.

Narazie wygląda tak mój beznadziejny program. Nie będe się powtarzał co chce jeszcze z nim zrobić bo to napisałem parę postów wyżej.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ogolnie ja bym to zrobil tak:

 

1. deklarujemy 3 tablice typu integer na 20 liczb oraz zmienne suma i przeniesienie

2. wczytujemy obie liczby

3. sprawdzamy ilosc cyfr w liczbach (np konwertujac na string)

4. majac ich dlugosc wpisujemy obie liczby do tablicy na ostatnie pozycje (czytajac od tylu petla w dol) po jednym znaku (jako Integer)

5. zagniezdzana petla wykonuj mnozenie na tablicach (domyslam sie, ze algorytm musi mnozyc pisemnie - aby go napisac, wykonaj na kartce mnozenie z przeniesieniem i napisz sobie operacje, ktore wykonujesz - robisz latwo, ale w rzeczywistosci to niezly algorytm, ktory musisz zapisac w poleceniach)

6. wypisujemy wynik (1 liczba, nowa linia,znak "x" + 2 liczba, nowa linia, kreski, nowa linia, wynik) -aby miec odstepy wklej odpowiednia ilosc spacji (ustalona na podstawie dlugosc wyniku, ktory bedzie dluzszy)

 

Ten algorytm ma wypisac postac pisemna, czy wykonywac krok po kroku pokazujac, co robi??

Jesli krok po kroku, to jest kawalek kodu do napisania..

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

1. Schemat, czyli zapisac tak, jak sie zapisuje - bez wykonania operacji. Tak?

2. Wiadomo, ze wynik bedzie mial wiecej cyfr niz skladniki. W sumie wystarcza 2 tablice 10 cyfrowe i jedna 20 cyfrowa. Wtedy wynik i nie powinien przekroczyc 20 cyfr.

3. Jesli zadeklarujesz tablice 20 cyfrowa i wezmiesz jako skladniki takie liczby, ze wynik bedzie dluzszy niz 20 cyfr (prznyajmniej 1 musialby byc wiekszy niz 10 cyrf), to pod koniec liczenia petla skonczy obliczenia na 1 elemencie tablicy i obetnie reszte (czyli najbardziej znaczace miejsca wyniku)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

wynik mnożenia dwóch lidzb pierwszej o n cyfrach i drugiej o m cyfrach jest conajwyżej m+n cyfrowy.

 

Więc napewno wynik powinien mieć wyznaczoną górną granice lidzby cyfr. Algorytm się składa z tylu kroków co cyfr w mnożnej.

jeden krok polega na sprawdzeniu czy najmniej znacząca cyfra mnożnej to nie zero , jeśli zero , wynik się nie zmienia a wskażnik dodawania oraz wsażnik cyfry mnożnej przesuwają się odpowiednio: na wyniku i na mnożnej o jedną pozycje w lewo , jeśli różna od zera , mnożymy mnożnik przez tą cyfre dodajemy wynik mnożenia do wyniku końcowego uwzględniając pozycje wskażnika dodawania, i przesuwamy obydwa wskażniki.(i dla cyfry równej zero i dla różnej od zera po na końcu kroku wykonujemy przesunięcie)

 

jeśli mnożna jest k cyfrowa - wykonujemy k takich kroków jak powyżej

i otrzymujemy n+k cyfr wyniku gdzie n to lidzba cyfr mnożnika , oczywiście np mnożenie 100 przez 3 wynik jest 3 cyfrowy ale dobrym zwyczajem przejetym z NKB powinno to wyglądać tak: 0100 * 0003 = 0000 0300 bo już 9999 * 9999 to 9998 0001 a niepotrzebną lidzbę zer można potem obciąć.

Edytowane przez Contrast

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

program mnozenie;uses Crt, Strings;vari, j : Integer;a, b : array[0..9] of Integer;x : array[0..9,0..9] of Real;z : array[0..19] of Real;ilocz, carry, s_linia, s_matryca, mnoznik : Real;temp: Integer;tempas: array[0..9] of String;temps: String;beginclrscr;writeln('Podaj 1 liczbe');readln(temp);Str(temp,temps);j:=9-length(temps);for i:=9 downto 0 do begin if i<=j then tempas[i]:='0' else tempas[i]:=temps[i-j]; end;for i:=0 to 9 doval(tempas[i],a[i],j);writeln('Podaj 2 liczbe');readln(temp);Str(temp,temps);j:=9-length(temps);for i:=9 downto 0 do begin if i<=j then tempas[i]:='0' else tempas[i]:=temps[i-j]; end;for i:=0 to 9 doval(tempas[i],b[i],j);for j:=9 downto 0 do begin  carry:=0;  for i:=9 downto 0 do   begin   ilocz:=a[i]*b[j]+carry;   x[i-(9-j),9-j]:=Int(ilocz-(10*Int(ilocz/10)));   carry:=Int(ilocz/10);   if (carry<>0) and (a[i]<>0) then    begin    write(i,j);    writeln(carry);    end;   end;  end;for j:=0 to 9 do begin  writeln;  for i:=0 to 9 do   begin   write(x[i,j]:1:0);   end;  end;s_linia:=0;s_matryca:=0;for j:=9 downto 0 do begin  mnoznik:=1;  s_linia:=0;  for i:=9 downto 0 do  begin  s_linia:=s_linia+(x[i,j]*mnoznik);  mnoznik:=mnoznik*10;  end;  s_matryca:=s_matryca+s_linia; end;writeln;write(s_matryca:10:0);readln;end.

Pierwsza rzecz, ktora mnie zaskoczyla, to problem z napisaniem tego kodu w Pascalu. Jesli chodzi o konwersje i zabawe na roznych zmiennych, to Pascal jest beznadziejny. Piszac to w C/C++ oszczedzilbym duzo miejsca i duzo nerwow..

 

Napisalem to raczej dla siebie, aby sprawdzic czy potrafie.. no i chyba potrafie :)

 

Wiem, ze troche namieszane, ale samo mnozenie dziala - jako algorytm. Kwestia wyswietlania i zwiekszenia tablicy dwuwymiarowej przy zmiennych powyzej 5 cyfr. Mi sie juz nie chcialo... bo pozno jest.

Mysle, ze od tego momentu sam sobie poradzisz. Jesli nie, to bedziemy kombinowac..

 

BTW:

Jesli ktos uwaza, ze ten kod ma za duzo zmiennych, jest zbyt skomlikowany i ogolnie ma duzo wad, to niech podejmie wyzwanie i sam cos napisze... :D

Mi sie kawa skonczyla.. ide spac.

Edytowane przez ULLISSES

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Zrobiłem część programu po swojemu. Zadeklarowałem tablice o typie string.

 

Mam teraz problem z mnożeniem. Pierwsza liczba pod kreską dobrze wychodzi,

ale druga, trzecia i następne już nie. W czym tkwi błąd?

 

Bardzo prosze o pomoc.

 

 

 

program mnozenie_pisemne;uses crt;type tablica = array[1..12,1..20] of string;var tab: tablica; a,b,la,lb: longint; s: string; i,j,dlgA,dlgB,pom, prze: byte;beginclrscr;{ czytanie 2 liczb }writeln('Podaj pierwszĄ liczb©');readln(a);writeln;writeln('Podaj drugĄ liczb©');readln(b);{ liczenie d�ugo�ci liczb }Str(a,s);dlgA:=length(s);str(b,s);dlgB:=length(s);writeln;writeln('D�ugo�† liczby pierwszej: ',dlgA,'. D�ugo�† liczby drugiej: ',dlgB,'.');{ sprawdzanie czy ujemne }If a<0 then begin  a:=a*-1;  dlgA:=dlgA-1;  tab[1,20-dlgA]:='-'; end;If b<0 then begin  b:=b*-1;  dlgB:=dlgB-1;  tab[2,20-dlgB]:='-'; end;lb:=b;la:=a;{ wpisywanie pierwszej liczby do tabeli }i:=1;for j:=20 downto 21-dlgA do begin  pom:= a mod 10;  a:= a div 10;  str(pom,s);  tab[i,j]:=s; end; { wpisywanie drugiej liczby do tabeli }i:=2;for j:=20 downto 21-dlgB do begin  pom:= b mod 10;  b:= b div 10;  str(pom,s);  tab[i,j]:=s; end;readln;{znak mnoľenia i podkre�lenie}If dlgA>dlgB then begin  i:=3;  for j:=20 downto 18-dlgA do                            begin                             tab[i,j]:='-';                            end;   tab[2,18-dlgA]:='X';  end              else begin i:=3; for j:=20 downto 18-dlgB do                           begin                            tab[i,j]:='-';                           end; tab[2,18-dlgB]:='X'; end;prze:=0;If (la=0) or (lb=0) then                     begin                      tab[4,20]:='0';                     end                    else                     begin                     For j:=1 to dlgB do                     begin                     b:=lb mod 10;                     lb:=lb div 10;                     For i:=1 to dlgA do                          begin                           a:=la mod 10;                           la:=la div 10;                           If la=0 then                                     begin                                     la:=a;                                     end;                           pom:=a*b+prze;                           prze:=0;                           If pom>9 then                               begin                               prze:=pom div 10;                               pom:=pom mod 10;                               end;                           str(pom,s);                           tab[3+j,22-i-j]:=s;                          end;                          If prze>0 then                                     begin                                     str(prze,s);                                     tab[4,20-i]:=s;                                     end;                           end;                     end;writeln('Przeniesienie: ',prze);writeln('b:= ',b);writeln('lb:= ',lb);writeln('la:= ',la);{ wy�witlanie tabeli}for i:= 1 to 12 do begin  writeln;  for j:= 1 to 20 do  begin   write(tab[i,j]:1);   end;  end;readln;end.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ale sobie życie utrudniasz. Przecież wystarczy odpowiednio wyświetlić to, co robi programik napisany przeze mnie..

 

Zaraz uruchomię, to co napisałeś i zobacze, gdzie jest problem..

 

Edit1:

Nie wiem, jak to zrobiłeś, ale program myli się w mnożeniu:

 32x32---- 6499 <---- ???

Szukam błędu... pewnie z przeniesieniem.

 

Edit2:

Ten kod jest zbyt zamieszany jak na moją cierpliwość do Pascala.

Poza tym (o ile dobrze widzę), to mnożysz OD PRZODU, co jest błędem matematycznym. Mnoży się od ostatniej liczby do pierwszej - chyba, że coś się zmieniło od czasu, gdy chodziłem do podstawówki.

Edytowane przez ULLISSES

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...