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 działa algorytm szybkie mnożenie w języku C? Wyjaśnienie kodu

hjkl3 12 Mar 2006 17:05 10053 12
REKLAMA
  • #1 2406044
    hjkl3
    Poziom 16  
    Posty: 267
    Pomógł: 1
    Ocena: 5
    Czytam sobie teraz jedną książkę o programowaniu - i doszedłęm do jakiegoś programu o nazwie "szybkie mnożenie" - może ktoś mi pomóc:
    Mam taki kod:

    //Szybkie mnożenie
    #include<stdio.h>
    #include<conio.h>
    int szybkie_mnozenie (int, int);
    int main()
    {
    int a, b, c;
    printf("podaj liczby do mnozenia: \na= ");
    scanf ("%d", &a);
    printf ("b= ");
    scanf("%d", &b);
    c=szybkie_mnozenie(a,b);
    printf("%d*%d=%d", a,b,c);
    getch();
    return 0;
    }

    int szybkie_mnozenie(int a, int b)
    {
    int c=0;
    while(b!=0)
    {
    if(b%2!=0)
    c=c+a;
    a=a*2;
    b=b/2;
    }
    return (c);
    }

    1. jeżeli "b" = 0 to program kończy swoje działanie i zwraca jako wynik mnożenia "c" czyli "0" - a czy nie powinno być : while(b!=0&&a!=0) żeby jeśli a=0 to też wynik był równy 0 ?????
    2. I czy może mi ktoś wyjaśnić jak działa program ten gdy b jest różne 0 - chodzi mi o tę część kodu:

    if(b%2!=0)
    c=c+a;
    a=a*2;
    b=b/2;

    o co w tym chodzi - jeśli reszta z dzielenia b przez 2 jest różna 0 to c przyjmuje wartość c+a..... przecież to jest bez sensu bo co jeśli reszta z dzielenia b przez 2 = 0 - nie rozumiem :( ?????
  • REKLAMA
  • #3 2406404
    hjkl3
    Poziom 16  
    Posty: 267
    Pomógł: 1
    Ocena: 5
    jak wpisze zmaiast return c - return a*b to to nie działa - rozumie ktoś działanie tego kodu? o co w nim chodzi? a może istnieje prostszy sposób zapisu mnożenia dwóch liczb ??
  • REKLAMA
  • Pomocny post
    #4 2406564
    johny_84
    Poziom 16  
    Posty: 235
    Pomógł: 13
    Ocena: 3
    
    #include<stdio.h> 
    #include<conio.h> 
    int main() 
    { 
     int a, b, c; 
     printf("podaj liczby do mnozenia: \na= "); 
     scanf ("%d", &a); 
     printf ("b= "); 
     scanf("%d", &b); 
    
     printf("%d*%d=%d", a,b,a*b); 
     
     system("PAUSE");
     return 0; 
    }


    Ja bym to jednak tak zrobił.

    Pozdro ;)
  • #5 2406655
    kordan11
    Poziom 18  
    Posty: 241
    Pomógł: 24
    Ocena: 10
    zgadzam się z przedmówcą jest to chyba najlepsza metoda, możesz jeszcze dodać instrukcje sprawdzającą czy któryś czynnik nie jest 0 ale to i tak wyjdzie w mnożeniu.
  • #6 2406750
    hjkl3
    Poziom 16  
    Posty: 267
    Pomógł: 1
    Ocena: 5
    dzięki - proste, jasne i zrozumiałem - wielkie dzięki
    a jakbym chciał napisać program na potęgowanie - to czemu mi źle wychodzi:
    //potęgowanie dwóch liczb
    #include<stdio.h>
    #include<conio.h>
    #include<math.h>
    int main()
    {
    int a, b, c;
    printf("podaj liczby do potegowania a^b: \na= ");
    scanf ("%d", &a);
    printf ("b= ");
    scanf("%d", &b);
    c=a^b;
    printf ("%d", c);
    getch ();
    return 0;
    }

    LUB:

    //potęgowanie dwóch liczb
    #include<stdio.h>
    #include<conio.h>
    #include<math.h>
    int main()
    {
    int a, b, c;
    printf("podaj liczby do potegowania a^b: \na= ");
    scanf ("%d", &a);
    printf ("b= ");
    scanf("%d", &b);
    c=pow(a,b);
    printf ("%d", c);
    getch ();
    return 0;
    }

    jak używam tego drugiego kodu to program działa, ale pojawia się najpierw napis że jest błąd:
    [Warning] converting to `int' from `double'
    dlaczego ??????? :)
  • #7 2406839
    kordan11
    Poziom 18  
    Posty: 241
    Pomógł: 24
    Ocena: 10
    to nie jest bład tylko ostrzeżenie, kompilator proponuje abyś zmienił typ danych z integer na double ponieważ integer ma mniejszy zakres wartości niż double.
  • #8 2406878
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #9 2406913
    hjkl3
    Poziom 16  
    Posty: 267
    Pomógł: 1
    Ocena: 5
    to ten kompilator źle mi radzi żebym zmienił z int na double, bo jak zmienie na double to zawsze jak podniosę do potęgi cokolwiek w programie to wychodzi zero...... :)
  • Pomocny post
    #10 2407010
    Konto nie istnieje
    Konto nie istnieje  
  • Pomocny post
    #11 2407314
    johny_84
    Poziom 16  
    Posty: 235
    Pomógł: 13
    Ocena: 3
    Dokładnie ;)

    musisz wiedziec, ze jak napisales
    
    int c;
    //to musi byc
    scanf("%d", &c);
    
    //a jesli 
    double c;
    //to 
    scanf("%lf", &c);
    
    //poprostu musza sie typy zgadzac :)
    


    Pozdro ;)
  • REKLAMA
  • #12 2407986
    hjkl3
    Poziom 16  
    Posty: 267
    Pomógł: 1
    Ocena: 5
    a no tak wielkie dzięki wam - poprzednio jak pisałem "double" to zapomniałem zmienić "%d" na "%lf" dzięki wielkie :D
  • #13 2415553
    Highway
    Poziom 12  
    Posty: 22
    Pomógł: 1
    Misiek.Power napisał:
    Wersja "pro" :)
    hjkl3 napisał:

    int szybkie_mnozenie(int a, int b)
    {
    int c=0;
    while(b)
    {
    if(b%2)
    c+=a;
    a*=2;
    b/=2;
    }
    return (c);
    }


    Sprawa jest elementarna. Wiadomo, że mnożenie liczb kosztuje sporo czasu procesora. Zatem ktoś wymyślił algorytm zamieniający "kosztowne" zwykłe mnożenie na równoważny zbiór sumowań i mnożen przez 2, co dla dowolnego procesora jest drobiazgiem (zwykłe przesunięcie rejestru w lewo).


    Przedstaw sobie b jako liczbe binarną i może Cię wtedy oświeci...

    Mnożenie a przez 3 (11b) - to suma 2a i 1*a...
    Mnożenie a przez 5 (101b)- to suma 1*4a i 0*2a i 1*a...
    Mnożenie a przez 12 (1100b) - to suma 1*8a i 1*4a i 0*2a i 0*a...
    i t d......

    Algorytm działa dla liczb całkowitych.

    POZDRAWIAM.

    P.S. funkcja pow wymaga argumentów typu double i zwraca double o ile dobrze pamiętam...


    Proponuję zastosować jeszcze przesunięcia zamiast mnożenia i dzielenia. Głupi kompilator może faktycznie wstawić mnożenie i dzielenie:
    Karygodne jest też zastosowanie operatora modulo (%).

    
    int szybkie_mnozenie(int a, int b) 
    { 
    int c=0; 
    while(b) 
    { 
    if(b & 1)  c+=a; 
    a<<=1; // przesunięcie o 1 bit w lewo = pomożenie przez 2
    b>>=1; // przesunięcie o 1 bit w prawo = podzielenie przez 2
    } 
    return (c); 
    } 
    


    pozdrowienia
    Highway
    www.idreams.pl

Podsumowanie tematu

✨ Dyskusja dotyczy algorytmu szybkiego mnożenia w języku C, który zastępuje tradycyjne mnożenie serią sum i operacji mnożenia przez 2, co jest efektywniejsze obliczeniowo. Algorytm działa na zasadzie analizy binarnej liczby mnożonej (b), gdzie jeśli najmłodszy bit jest ustawiony (b%2 != 0 lub b & 1), do wyniku dodawana jest aktualna wartość a. Następnie a jest podwajane (a = a*2 lub a = 1), aż b osiągnie zero. Wskazano, że użycie operatora modulo (%) i mnożenia/dzielenia może być mniej optymalne niż przesunięcia bitowe. Poruszono także kwestię warunku pętli while(b != 0) i czy należy uwzględnić a != 0, jednak mnożenie przez zero jest naturalnie obsługiwane przez algorytm. W dalszej części omówiono problem z potęgowaniem w C, gdzie operator ^ jest błędnie używany jako potęgowanie, a funkcja pow z biblioteki math.h wymaga typów double i zwraca double, co powoduje ostrzeżenia przy przypisaniu do int. Podkreślono konieczność zgodności typów w scanf i printf (%d dla int, %lf dla double). Zaproponowano prostsze rozwiązania mnożenia i poprawne użycie potęgowania z typami zmiennoprzecinkowymi.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA