logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak zapisać pseudokod mnożenia dużych liczb całkowitych z tablic?

one_eddie 17 Gru 2005 19:26 1183 4
REKLAMA
  • #1 2092706
    one_eddie
    Poziom 25  
    Posty: 973
    Pomógł: 62
    Ocena: 14
    Chodzi dokładnie o zapis mnożenia dowolnie wielkiej liczby całkowitej, przez dowolnie wielką całkowitą, (przechowywane w tablicach).
  • REKLAMA
  • Pomocny post
    #2 2095632
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 134
    No to przypomnij sobie z podstawówki mnożenie sposobem pisemnym :]

    a na tablicach (liczby w formacie binarnym, najmniej znaczacy bajt ma indeks 0):

    unsigned char a[N], b[N], c[N+N];
    int p1, p2;
    
    for(p1 = 0; p1<N+N; p1++)
      c[p1] = 0;
    
    for(p1 = 0; p1<N; p1++) {
      for(p2 = 0; p2<N; p2++) {
        c[p1+p2] += (a[p1] * b[p2]) & 0xff;
        c[p1+p2+1] += (a[p1] * b[p2]) >> 8;
      }
    }
  • REKLAMA
  • #3 2095717
    one_eddie
    Poziom 25  
    Posty: 973
    Pomógł: 62
    Ocena: 14
    shg napisał:
    No to przypomnij sobie z podstawówki mnożenie sposobem pisemnym :]

    a na tablicach (liczby w formacie binarnym, najmniej znaczacy bajt ma indeks 0):

    unsigned char a[N], b[N], c[N+N];
    int p1, p2;
    
    for(p1 = 0; p1<N+N; p1++)
      c[p1] = 0;
    
    for(p1 = 0; p1<N; p1++) {
      for(p2 = 0; p2<N; p2++) {
        c[p1+p2] += (a[p1] * b[p2]) & 0xff;
        c[p1+p2+1] += (a[p1] * b[p2]) >> 8;
      }
    }


    Nie czekałem na gotowca - ale wielkie dzięki.
  • REKLAMA
  • #4 2099389
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 134
    Aj, o jednym zapomniałem - dodawanie będzie generować przeniesienia.
    Algorytm działa tylko dla liczb dodatnich.
    Poprawiona wersja:

    unsigned char a[N], b[N], c[N+N];
    unsigned int p1, p2, p3, resm, resa;
    
    for(p1 = 0; p1<N+N; p1++)
      c[p1] = 0;
    
    for(p1 = 0; p1<N; p1++) {
      for(p2 = 0; p2<N; p2++) {
        resm = a[p1] * b[p2];
        resa = c[p1+p2] + (resm & 0xff);
        c[p1+p2] = resa & 0xff;
        resa >>= 8; /* przeniesienie z dodawania */
        resa = c[p1+p2+1] + (resm >> 8) + (resa >> 8); /* MSB iloczynu + przeniesienie z poprzedniego dodawania */
        c[p1+p2+1] = resa & 0xff;
        resa >>= 8; /* i kolejne przeniesienie */
    
    /* powtarzamy dopóki nie będzie co przenosić */
        for(p3 = p1+p2+2; resa > 0; p3++) { 
          resa = c[p3] + resa; /* dodać przeniesienie */
          c[p3] = resa & 0xff;
          resa >>= 8; /* i nastepne przeniesienie */
        }
      }
    }


    Pętla for(p3 = p1+p2+2; resa > 0; p3++) z pozoru może wyglądać niebezpiecznie (potencjalne przekroczenie zakresu tablicy - maksymalny indeks może wynieść N+N), ale dla ostatniego elementu nigdy nie zostanie wygenerowane przeniesienie (resa zawsze == 0), więc wszystko jest w porządku.
  • #5 2258878
    one_eddie
    Poziom 25  
    Posty: 973
    Pomógł: 62
    Ocena: 14
    Wkoncu i tak samodzielnie doszedlem do rozwiazaina problemu, nie wiem dlaczego ale kod przedstawiony przez shg nie dzialal poprawnie. Nie dochodzilem przyczyny.

    Wszystkim dziekuje za pomoc.
REKLAMA