przekroczenie max. zakresu liczb

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;
}
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.

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

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

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 * 1234[/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

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