[Fortran] Problema divisione tra real

Lory314
Ciao a tutti.
Ho un problema che, onestamente, dopo qualche anno di programmazione, pensavo di non dover incontrare....anche perchè mi fa sentire un incapace.
Purtroppo mi tocca utilizzare Fortran come linguaggio di programmazione.
Quello che dovrei fare è semplicemente una divisione, ma diciamo che il risultato che mi da il compilatore è "sbagliato".
Riporto per semplicità solo i pezzi di codice che mi danno problemi.
real h
integer N

print*, "Numero di quadrati per lato: "
read*, N

h=real(1)/N
print*, h



Ora, scegliendo ad esempio N = 20, h = 5.00000007E-02....
Invece dovrebbe essere semplicemente 5E-02...
Penso ci siano due modi per risolvere il problema:
1) Fare in modo che h = 5E-02. Una mia idea era quella di sottrarre ad h il resto della divisione tra h e, ad esempio, 0.0001, in modo da troncare h alla quarta cifra decimale. Ho testato questa cosa su altri linguaggi (octave, matlab) e funziona. In fortran NO!
2) Dato che il mio obiettivo è scrivere dati su un file di testo, fare in modo che vengano scritte solo le prima 4 (ad esempio) cifre decimali. Questo però non ho idea di come farlo.

Qualcuno riesce ad aiutarmi?

Grazie

Risposte
apatriarca
Octave e Matlab usano variabili con una precisione maggiore di quella usata nel tuo esempio fortran. Usano infatti delle variabili floating point a doppia precisione. Utilizza quindi double precision al posto di real.

Lory314
Avevo già provato, ma continua a darmi lo stesso problema.


double precision h

	print*, "Numero di quadrati per lato: "
	read*, N

	h=real(1)/N
	print*, h
	h = h - mod(h,0.0001)



Sempre per N=20, mi esce h = 5.00000007450580597E-002

apatriarca
È evidente che il calcolo non viene fatto con doppia precisione. La ragione credo risieda nel fatto che converti il valore 1 a real e quindi real(1)/N credo venga calcolata con precisione singola e poi convertita in precisione doppia quando assegni l'espressione ad h. Prova a scrivere 1.0d+0/N invece di real(1)/N.

Lory314
	double precision x,y,h

	print*, "Numero di quadrati per lato: "
	read*, N

	h=(1.0d+0)/N
	print*, h
	h = h - mod(h,0.000001)
	print*, h



Purtroppo non funziona ancora....ottengo h = 5.00000000000000028E-002

apatriarca
Partiamo prima di tutto da presupposto che 0.005 non sia rappresentabile in binario con un numero finito di cifre. Per cui il risultato non sarà mai preciso. h è probabilmente il valore più vicino a quello corretto tra quelli rappresentabili in un real e in un double precision rispettivamente. Se il problema è solo la stampa dovresti poter usare write con qualche formato opportuno.

Lory314
Si, alla fine il problema sarebbe solo quello di scrivere numeri simili ad h con un numero minore di cifre decimali rispetto a quello che fa ora. Però speravo di risolvere il problema all'origine, sia perchè con MatLba/Octave si riesce a fare quello che vorrei, sia perchè, avendo imparato Fortran da autodidatta, non sono molto ferrato sulla stampa in formati particolari. Avevo provato a dare un'occhiata in rete, ma non ero riuscito a capirne molto.

Rggb1
Normalmente le implementazioni dei compilatori Fortran usano gli output non formattati (ma sarebbe più esatto dire con formato de facto) usando, per quanto riguarda i numeri single/double, la maggiore precisione disponibile.

Comunque l'uso di I/O formattato o equivalentemente degli statement FORMAT non è assolutamente difficile, pe. dà un'occhiata a questo
http://www.mat.uniroma1.it/~seghini/fortran/io.html

Lory314
Ok, ora ho capito l'errore che facevo nell'usare l'output formattata. Purtroppo non avevo mai trovato spiegazioni così chiare.
Grazie.

giuscri
/OT
Posso chiedere in quali occasioni succede di voler usare il Fortran?
OT/

apatriarca
Fortran è ancora il linguaggio più usato in alcuni ambienti, legati soprattutto al calcolo scientifico. Le ragioni del suo uso sono dopotutto le solite: un sacco di codice scritto in tale linguaggio e un sacco di programmatori esperti in tale linguaggio e non in altri. E poi si tratta di ambienti in cui le performance contano molto.

Lory314
Purtroppo non è un volere ma è un dovere. Sto facendo uno stage presso un centro di ricerca in cui usano fortran per risolvere un problema di piastre con gli elementi finiti.
Avrei preferito usare Matlab (o Octave) perchè almeno ci si deve preoccupare di meno di aspetti di programmazione e riflettere di più su altri aspetti.
Però mi sono dovuto adattare e impararmi da solo il Fortran (o per lo meno quello che poteva servirmi), dato che da me in università non si usa.

apatriarca
[OT] Quindi stai sviluppando un solver? [/OT]

Lory314
Diciamo di si. Il solver è già scritto. Mi è stato chiesto di migliorarlo in modo da risolvere il problema usando mesh più fini.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.