przekroczenie max. zakresu liczb

Odpowiedz Nowy wątek
2008-03-09 13:07
0

Witam wszystkich którym chciało sie tu zajrzeć.
Na początek przedstawię co chciałem zrobić:
mianowicie w bliżej nieokreślonym celu ;-P chce utworzyć macierz której komórki będą miały wartości zgodnie z wzorem:
A[i][j]=sqrt(2*j+1)*(silnia(i)*silnia(i))/(silnia(i+j+1)*silnia(i-j))
Wzór ten jest też pod adresem(czytelniejsza forma):
http://www.imagic.pl/public/pview/121758/index_1.gif

Rezultat moich wypocin jest poniżej :-)

Teraz problem:
Przy rozmiarach macierzy np: n= 9 otrzymuje bardzo duże lub ujemne wyniki w komórkach z duzymi indeksami np: M[9][9] co nie powinno mieć miejsca, natomiast przy małych rozmiarach macierzy wszytko gra [green] .

Stąd doszedłem do wniosku ze ponieważ używam silni to może następować przepełnienie zmiennych, jednak użycie zmiennych typu long nie pomogło [glowa]

wyniki otrzymane za pomocą specjalistycznego programu :> są pod adresem(czyli takie jakie powinny być) jest:
http://www.imagic.pl/public/pview/121759/dddd.gif

wyniki z progrmu mojego:
http://www.imagic.pl/public/pview/121763/index_1.gif

Za wszelkie wskazówki jak sie z tym uporać i poświęcony czas z góry thx:

oto rezultat moich wypocin kompilowany pod visual studio c++ 6.0:

#include <iostream>
#include <cmath>
#include <stdio.h>
#include <fstream>//operacje na plikach

using namespace std;

#define SIZE 15

long double A[SIZE][SIZE];

// funkcja zapisujaca do pliku
void Zapisz(int n)
{

    FILE * pFile;
    int i,j;

    pFile = fopen ("dane.txt","a");
// umieszcza odpowiedni napis przed macierza    

// zapis macierzy   
    for(i=0;i<n;i++)
    {
        fprintf (pFile,"|");
        for(j=0;j<n;j++)
        {

            fprintf (pFile,"% lf ", A[i][j]);

        }
        fprintf (pFile,"| \n");
    } 

    fclose (pFile);     
}

// funkcja pomocnicza obliczajaca silnie
long int silnia(int i)
{
    int k;
    long int wynik=1;

    for(k=1;k<=i;k++)
        wynik=wynik*k;

    return wynik;
}

// macierz 
void dL(int n)
{

    int i,j;

    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            if(i-j>=0)
                A[i][j]=sqrt(2*j+1)*(silnia(i)*silnia(i))/(silnia(i+j+1)*silnia(i-j));
            else A[i][j]= 0.0;
        }
    }
    //drukowanie macierzy
    cout<<"Macierz L z daszkiem:"<<endl;

    for(i=0;i<n;i++)
    {
        cout<<"|";
        for(j=0;j<n;j++)
        {
            printf("% 2.5lf ", A[i][j]);
        }
        cout<<"|"<<endl;
    }
    Zapisz(n);
}

int main(int argc, char* argv[]){

    dL(9);

    return 0;
}

Pozostało 580 znaków

2008-03-09 13:33
0
(%i5) F(i,j) := sqrt(2*j+1)*(i!*i!)/((i+j+1)!*(i-j)!);
                                  sqrt(2 j + 1) (i! i!)
(%o5)                  F(i, j) := ---------------------
                                  (i + j + 1)! (i - j)!
(%i6) F(9, 9);
                                            - 1/2
                             131681894400 19
(%o6)                        --------------------
                               6402373705728000
(%i7) float(F(9, 9));
(%o7)                        4.7185465625372625e-6

O ile wynik końcowy nie jest taki wielki, o tyle wyniki pośrednie wykraczają nawet poza long. Wniosek - używaj bigint.


Pozostało 580 znaków

2008-03-09 13:43
0

dzięki za odpowiedź jednak przyznam ze pierwszy raz spotykam sie z typem bigint w c++ ?
czy można byłby by jaśniej co do użycia tego cuda ;]
bo mi jakoś nie wychodzi pod Visual c++ 6.0

Pozostało 580 znaków

2008-03-09 13:55
0

to jest ogolna nazwa biblioteczek do obslugi bardzo duzych liczb, nie mieszczacych sie nijak w zadnym ze standardowych typow. google, wybierz jakas, sciagnij i uzywaj zamiast long/double


no to pojechałem z nieobecnością.. chwila przerwy i prawie rok przeleciał

Pozostało 580 znaków

2008-03-09 14:06
mgr.Dobrowolski
0

pomińmy czynnik sqrt(2j+1)
sprawdziłbym, jak się ma f(j,i+1) do f(j, i), to jedno
a po drugie, przecie nikt przy zdrowych zmysłach nie liczy np. Newtona mnożąc i dzieląc przez siebie silnie
binomial(6,2)= 6!/4!/2! = 6/15/2
inaczej[code]
1
23456
----------------- = ... sam sobie uprościsz
12 123*4[/code]
Czujesz pan zasadę?

gp > f(i,j)=i!i!/((i+j+1)!(i-j)!)
gp > for(i=0,10,{
for(j=0,i,
print1(f(i,j)," "););print;
);}
1
1/2 1/6
1/3 1/6 1/30
1/4 3/20 1/20 1/140
1/5 2/15 2/35 1/70 1/630
1/6 5/42 5/84 5/252 1/252 1/2772
1/7 3/28 5/84 1/42 1/154 1/924 1/12012
1/8 7/72 7/120 7/264 7/792 7/3432 1/3432 1/51480
1/9 4/45 28/495 14/495 14/1287 4/1287 4/6435 1/12870 1/218790
1/10 9/110 3/55 21/715 9/715 3/715 3/2860 9/48620 1/48620 1/923780
1/11 5/66 15/286 30/1001 2/143 3/572 15/9724 5/14586 5/92378 1/184756 1/3879876

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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