Si je veux que les valeurs obtenus dans un programme depasse 10^-100, comment faire?
1.64367061E-77 1.39682283E-78 1.18710668E-79 1.00891694E-80 NAN NAN
Si je veux que les valeurs obtenus dans un programme depasse 10^-100, comment faire?
1.64367061E-77 1.39682283E-78 1.18710668E-79 1.00891694E-80 NAN NAN
il faut jouer avec le paramètre kind de ton real...
te dis que tu utilise un double précision (codé sur 8 octets) en gros (c'est pas toujours vrai sur certaines machines) mais le paramètre kind te dit sur combien d'octets tu code ton nombre du coup pour un double précision les bornes sont: 5.0 * 10-324 .. 1.7*10328 (comme dans la plupart des languages codant sur 8 octets
Code : Sélectionner tout - Visualiser dans une fenêtre à part real(kind=8) :: res
du coup 10^-100 est bien pris en compte... attention cela dit, en général, tomber sur ce genre de valeur signifie généralement que l'on fleurte avec l'erreur machine!
et si je veux l afficher,
quelle type de format faut utiliser
voila mon code,
je travaille en double precision
il me donne
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 print 10,(diffl(i),i=1,M) 10 format('A=',3(D5.5,1X))
A=***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
***** ***** *****
Salut!
Ce n'est pas un problème de Fortran mais une limitation de ton processeur qui suit la norme IEEE 754.
De toute manière, il faudrait t'interroger sur la signification de nombres aussi petits. Comment les as-tu obtenus?
Jean-Marc Blanc
Bon , ce sont des valeurs prores d un operateur pseudo differentiel,
j ai l ai obtenu par un algorithm, mais j ai besoin de ce nombre meme si l est tress petit, car je l injecte ensuite dans une deuxieme etape d un algorithme,
l important pour moi le format.
voila mon grand code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 program r integer M,V parameter(M=30) parameter(V=75) parameter(pi=3.1415926535d0) double precision Pr(M-1),qr(M-1),dsup(V),dinf(V),diffl(V) Call vp(V,M,Pr,qr,dsup,dinf,diffl) print 10,(diffl(i),i=1,M) 10 format('A=',3(D5.5,1X)) C write(*,'E4.10') diffl end subroutine vp(S,N,P,q,difsup,difinf,diffLambda) integer i,j,N,u,S double precision h,Csupp,Cinf,gamma double precision g(N),P(N-1),difsup(S) double precision gamainf(N),q(N-1),difinf(S),diffLambda(S) h=0.01d0 do i=1,N-1 g(i)=gamma(90,500,i*h) enddo g(N)=1.0d0 do j=1,N-1 P(j)=(g(j+1)+g(j))/(g(j+1)-g(j)) enddo do u=1,S Csupp = P(1)/(h**(2*u)) do j=2,N-1 Csupp =(P(j)*Csupp+(j*h)**(-2*u))/(P(j)+Csupp*(j*h)**(2*u)) enddo difsup(u)= -(2.0d0*u)/(1.d0+Csupp) enddo do i=1,N-1 gamainf(i)=gamma(90,500,(i-1)*h) enddo gamainf(N)=1.0d0 do j=1,N-1 q(j)=(gamainf(j+1)+gamainf(j))/(gamainf(j+1)-gamainf(j)) enddo do u=1,S Cinf = q(1)/(h**(2*u)) do j=2,N-1 Cinf=(q(j-1)*Cinf+((j-1)*h)**(-2*u))/(q(j-1) & +Cinf*((j-1)*h)**(2*u)) enddo difinf(u)= -(2.0d0*u)/(1.d0+Cinf) enddo do j=1,S diffLambda(j)=(difinf(j)+difsup(j))/2.0d0 enddo return end function gamma(n,m,x) double precision x,h,pi,f1,f2,gamma integer n,m,i h=0.4d0/dble(m) pi=4.d0*datan(1.d0) gamma=(h*n/(6.d0*dsqrt(2.d0*pi)))*(dexp(-0.5d0*(n**2) & *(x+0.2d0)**2)+dexp(-0.5d0*(n**2)*(x-0.2d0)**2) & +2.d0*f1(n,m,x)+4.d0*f2(n,m,x))+1.d0 return end function f1(n,m,x) double precision x,h,f2 f1=0.d0 h=0.4d0/dble(m) do i=1,m-1 f1=f1+dexp(-0.5d0*(n**2)*(x-i*h+0.2d0)**2) enddo return end function f2(n,m,x) double precision x,h,f2 h=0.4d0/dble(m) f2=0.d0 do i=0,m-1 f2=f2+dexp(-0.5d0*(n**2)*(x-i*h-h/2.d0+0.2d0)**2) enddo return end
bonjour,
si c'est juste un problème de format, essaie avec ça:
Code : Sélectionner tout - Visualiser dans une fenêtre à part 10 format('A=',3(D13.5,1X))
au niveau du format dans le "dx.y" le x représente le nombre total de caractères et y le nombre de décimales or un nombre affiché de cette menière est écrit: "0.######D+00" il faut donc que x>6+y voir 7+y si tu veux trois chiffre en exposant.... y représente le nombre de #
Peut être que le format a résolu ton problème. Cependant quand tu as quelque chose du genre :
***** **** ******
C'est un problème de format, par contre NaN signifie généralement Not a Number, donc ça n'a rien à voir avec le format. C'est que tu dois peut être diviser par 0 ou avoir encore un dépassement de capacité.
Salut!
Cela n'implique pas que ça ait un sens.j ai l ai obtenu par un algorithm,
Est-ce qu'elles sont toutes aussi petites ou est-ce qu'il y en a aussi de beaucoup plus grandes?ce sont des valeurs prores
Jean-Marc Blanc
le problème est revenu,
j ai tourné mon code , et c est que j ai eu a la fin:
alors il ne comprends pas les nombres petits?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 0.35312E-71 0.24712E-72 0.17387E-73 0.12297E-74 0.87415E-76 0.62451E-77 0.44834E-78 0.32338E-79 0.23433E-80 0.17056E-81 0.12468E-82 0.91519E-84 NAN NAN NAN NAN NAN NAN
Pour Jean Marc,
enfaite c est l expression $Lambda(i)-i$ ,
Les valeurs que tu donnes avec les NaN sont celles de ta matrice ou les valeurs propres ?
Avec quoi tu diagonalise ta matrice ?
Je pense que tu n'as pas de problème de petits nombres mais qu'il y a une erreur dans ton code, du genre division par zéro.
ca c est vrai,
car si tu regarde mon code :
gamma(90,500,i*h) c est une approximation d une fonction constante discontinue
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 do i=1,N-1 g(i)=gamma(90,500,i*h) enddo g(N)=1.0d0 do j=1,N-1 P(j)=(g(j+1)+g(j))/(g(j+1)-g(j)) enddo
Salut!
A voir l'évolution de cette discussion, ce n'est pas un problème de Fortran mais de ce que tu veux calculer et de comment tu veux le faire. En conséquence, je la transfère dans le forum algo/maths.
Jean-Marc Blanc
Salut!
Une fonction constante est nécessairement continue.une fonction constante discontinue
Si, au lieu de tourner autour du pot, tu nous disais enfin ce que ton programme est censé faire, on avancerait plus vite. Tu nous parles des valeurs propres d'une matrice; mais quelle matrice? d'où vient-elle? quelle est sa taille et quelles sont ses propriétés? que représentent réellement ses valeurs propres?j ai tourné mon code , et c est que j ai eu a la fin:
Est-ce que cette expression a un sens si les Lambda sont les valeurs propres, donc des réels alors que i est un indice, donc un entier?$Lambda(i)-i$
Jean-Marc Blanc
Cher Jean Marc,
je vous ai dit valeurs propres d un operateur pseudodifferentiel, et PAS une matricE!!
i etant l indice mais je l ecrit dans mon code dble(i)
Bonjour,
Vue la tête de ton code, on dirait que tu cherches à calculer une sorte de limite avec ton : " P(j)=(g(j+1)+g(j))/(g(j+1)-g(j)) " et ce qui précède.
Si tu veux calculer un truc du style :
P(x) = limite quand h tend vers 0 de ( g(x+h)+g(x) )/( g(x+h) - g(h) ), plus tu prendras un h petit pour avoir une bonne résolution, plus tu tendras vers la division par zéro au sens de la machine, donc plus ton calcul sera faux...
C'est gênant, mais voilà, tu travailles sur une machine et il faut adapter tes méthodes. Si tu veux une limite précise, tu peux par exemple la chercher par une méthode itérative, en évitant ainsi d'aller trop près des divisions par zéro.
Exemple :
pour chaque x pour lequel tu veux une valeur P(x)
prendre h = 1.0
calculer p0 = ( g(x+h)+g(x) )/( g(x+h) - g(h) )
début de boucle infinie
diviser h par 2.0
calculer p1 = ( g(x+h)+g(x) )/( g(x+h) - g(h) )
SI abs(p1 - p0) < precision_recherchee ALORS sortir de la boucle;SINON FIN SI
p0 = p1
fin de boucle infinie
mémoriser la valeur p1 pour x
NB : Tu peux aussi mettre un nombre limite d'itérations dans ta boucle. Si tu dépasses ce nombre limite, alors, la limite n'existe pas (ce qui peut expliquer un NaN dans ta méthode de calcul).
Bye, en espérant que ça t'aide
Salut!
Je ne vois vraiment pas comment tu peux stocker un opérateur dans un ordinateur.valeurs propres d un operateur pseudodifferentiel
Si tu veux qu'on t'aide, décris ton problème dans son ensemble: ce qui t'est donné, ce qu'on te demande, ce que tu as déjà fait, quel est ton opérateur, comment tu l'as obtenu, ce que tu veux faire avec ses valeurs propres.
Jean-Marc Blanc
je vous l algorithme des valeurs propres en attachement.
en fait mon operateur (si vous savez bien les edp) A qui prends une fonction f definie sur le bords d un domaine borne et donne $\partial_n u$ avec $u$ etant la solution du probleme div(\gamma\nabla u)=0 sur le domaine et $u=f$ sur le bord.
cet algorithme marche pour $\gamma$ radiale et au moin C^2.
mois je le test pour $\gamma$ radiale discontinue : je l approche par une suite $\gamma)_n$ assez reguliere et ensuite j applique l algorithme.
voila
Partager