mi3s Δημοσ. 29 Νοεμβρίου 2009 Δημοσ. 29 Νοεμβρίου 2009 Έχω μια άσκηση να κάνω αλλά είμαι ψιλοάσχετος με την fortran ακόμη. Η εκφώνηση λέει:Να γραφεί και να εκτελεστεί πρόγραμμα που διαβάζει από ένα αρχείο διαφορετικές τιμές(το αρχείο δεδομένα) μιας πραγματικής μεταβλητής χ(μια τιμή ανά record)και να υπολογίζει την τιμήτης συνάρτησης από τις σχέσεις(όπως τις γράφω στον κώδικά) Το πρόγραμμα θα πρέπει να ελέγχει στην πρώτη σχέση αν ο παρανομαστής μηδενίζεται για να αποφεύγεται ο υπολογισμός της f. χ φ ************************* 4.3 9.599505 3.0 ΜΗΔΕΝΙΖΕΤΑΙ Ο ΠΑΡΑΝΟΜΑΣΤΗΣ -3.2 60.00000 ΚΤΛ > open(unit=1,file="dedomena.txt") read(1,*)x open(unit=2,file="apotelesmata.txt") write(2,7) 7 FORMAT(6x,"X",6X,"F",/20('*')) if (x==3) then 5 FORMAT(6X,F5.1,3X, 'MHDENIZETAI O PARANOMASTHS') WRITE(2,5)x else if (x>0) then f=((x**(3/10))+5*x**(3/4)-4)/(x-3) 4 FORMAT(6X,F5.1,6X,F10.4) write(2,4)x,f else IF(x<=0) then f=5*(x**2)-(2*x)+3 write(2,4)x,f endif endif end Το πρόβλημα είναι ότι εκτός ότι είμαι σίγουρος ότ ιέχω γράψει σωστά την πρώτη εξίσωση μου βγάζει άλλο αποτέλεσμα.Επίσης σταματάει εκεί και το αρχείο εξόδου λειτουργεί σωστά μόνο για την πρώτη εντολή.Η δεύτερη τιμή είναι η 3.0 η πρώτη η 4.3.Τι μπορεί να έχω λάθος? Ευχαριστώ εκ των προτέρων. Τα αποτελεσματα να γράφονται σε αρχείο με μορφή
Vas77 Δημοσ. 30 Νοεμβρίου 2009 Δημοσ. 30 Νοεμβρίου 2009 Μερικές παρατηρήσεις: 1) Πάντα να χρησιμοποιείς το implicit none στην αρχή του προγράμματος 2) Οι μεταβλητές χ,f είναι real. Οπότε, καλό είναι να πολλαπλασιαζεις με real αριθμού και όχι με ακέραιους. Δηλαδή, αντί > f=((x**(3/10))+5*x**(3/4)-4)/(x-3) γράψε > f=((x**(3.d0/10.d0))+5.d0*x**(3.d0/4.d0)-4.d0)/(x-3.d0) 3) Επειδή υπάρχουν round of errors, ποτέ ένας real αριθμός δεν έχει μόνο ένα δεκαδικό ψηφίο. Δηλαδή, εσύ μπορείς να ορίσεις ότι x=3.0 όμως για τον υπολογιστή, η μεταβλητή x=3.00000001 (round of errors). Για αυτό το λόγο όταν συγκρίνεις δύο real αριθμούς ελέγχεις τη διαφορά τους. Οπότε η εντολή > if (x==3) πρέπει να γίνει > if(abs(x-3.d0)<1.d-5) 4)Το απότελεσμα της διαίρεσης 3/4 μπορεί να είναι 0. Επειδή οι αριθμοί 3 και 4 είναι ακέραιοι ο compiler μπορεί να σου δώσει το απότελεσμα σε μορφή ακέραιου αριθμού. Αντί για 3/4 γράψε 3.d0/4.d0
mi3s Δημοσ. 30 Νοεμβρίου 2009 Μέλος Δημοσ. 30 Νοεμβρίου 2009 Βασικά όταν έβαλα το implicit none μου έβγαλε σφάλμα και υπέθεσα ότι δεν χρειάζεται.Αντικατέστησα την εντολή και βγήκε το σωστό αποτέλεσμα,άλλαξα και την δεύτερη που είπες αυτη με το χ==3 αλλά πάλι δεν εμφάνισε τίποτε.Τι μπορεί να φταίει? Επίσης το d είναι απαραίτητο να μπαίνει ή αρκεί μια .? Το abs τι ακριβώς σημαίνει?(άσχετος γαρ)
Vas77 Δημοσ. 30 Νοεμβρίου 2009 Δημοσ. 30 Νοεμβρίου 2009 Βασικά όταν έβαλα το implicit none μου έβγαλε σφάλμα και υπέθεσα ότι δεν χρειάζεται.Αντικατέστησα την εντολή και βγήκε το σωστό αποτέλεσμα,άλλαξα και την δεύτερη που είπες αυτη με το χ==3 αλλά πάλι δεν εμφάνισε τίποτε.Τι μπορεί να φταίει?Επίσης το d είναι απαραίτητο να μπαίνει ή αρκεί μια .? Το abs τι ακριβώς σημαίνει?(άσχετος γαρ) Με την εντολή implicit none πρέπει να δηλώσεις όλες τις μεταβλητές που θα χρησιμοποιήσεις στον κώδικα. Αν έχεις δηλώσεις τις μεταβλητές σου ως real τότε αρκεί η ".", αν όμως είναι double precision τότε χρειάζεται το .d0 To abs(absolute) σημαίνει απόλυτη τιμή. Δοκίμασε να βγάλεις τα format έξω από το if. Επίσης πριν το end, γράψε close(unit=1,status='keep'). Καλό είναι όταν ανοίγεις ένα αρχείο να δηλώνεις το status του αρχείου. open(unit=1,file='blah.txt' status='unknown') Το status μπορεί να είναι old, new, unknown. Χρησιμοποιήσε το τελευταίο. Βέβαια, δεν πρέπει να ξεχνάς να κλείνεις αυτό το αρχείο.
mi3s Δημοσ. 30 Νοεμβρίου 2009 Μέλος Δημοσ. 30 Νοεμβρίου 2009 Όσο και να δοκίμασα παίρνει μόνο την πρώτη τιμή και τις υπόλοιπες δεν τις διαβάζει καθόλου.
DarkOrion Δημοσ. 1 Δεκεμβρίου 2009 Δημοσ. 1 Δεκεμβρίου 2009 Επίσης, μπορείς στην αρχή του κώδικα να γράψεις implicit double precision (a-h,o-z) Αυτό σημαίνει ότι όλες οι μεταβλητές που ξεκινάνε με γράμμα a-h ή ο-z είναι αυτόματα διπλής ακρίβειας. Θα μπορούσες να βάλεις a-z, αλλά δεν θα σου το συνέστηνα γιατί η fortran χρησιμοποιεί τις ακέραιες μεταβλητές, και καλό είναι να μην το πειράζεις.
sivadWS2 Δημοσ. 1 Δεκεμβρίου 2009 Δημοσ. 1 Δεκεμβρίου 2009 Του λες κάπου να διαβάσει περισότερες από μία τιμές; Μια read έχεις στη αρχή διαβάζει μια τιμή και τίποτα άλλο....
Vas77 Δημοσ. 1 Δεκεμβρίου 2009 Δημοσ. 1 Δεκεμβρίου 2009 Όσο και να δοκίμασα παίρνει μόνο την πρώτη τιμή και τις υπόλοιπες δεν τις διαβάζει καθόλου. Γιατί δε μας το είπες αυτό από την αρχή Διαβάζει την πρώτη γιατί του λες να διαβάσει την πρώτη (έχεις μόνο 1 read). Γράψε το εξής > open(unit=1,file="dedomena.txt") do while(.not.eof(1)) read(1,*)x τον υπόλοιπ κώδικα end do
mi3s Δημοσ. 1 Δεκεμβρίου 2009 Μέλος Δημοσ. 1 Δεκεμβρίου 2009 Επιτέλους ρε φίλε!Έγινε όπως το ήθελα,ακριβώς.Πες μου λίγο τι ακριβώς σημαίνει κιόλας αυτό που έχεις μέσα στο while.Ευχαριστώ πολύ. Eπίσης αυτός τα ήθελε σε μορφή .lst έβαλα τις επιλογές που έλεγε βγήκε ένα txt αλλά δεν έχει μεσα τα αποτελέσματα που αυτός για αυτό υποτίθεται το θέλει σε τέτοια μορφή.
Vas77 Δημοσ. 2 Δεκεμβρίου 2009 Δημοσ. 2 Δεκεμβρίου 2009 Επιτέλους ρε φίλε!Έγινε όπως το ήθελα,ακριβώς.Πες μου λίγο τι ακριβώς σημαίνει κιόλας αυτό που έχεις μέσα στο while.Ευχαριστώ πολύ. Eπίσης αυτός τα ήθελε σε μορφή .lst έβαλα τις επιλογές που έλεγε βγήκε ένα txt αλλά δεν έχει μεσα τα αποτελέσματα που αυτός για αυτό υποτίθεται το θέλει σε τέτοια μορφή. Δεν ξέρω τι είναι το lst αρχείο. Πιστεύω ότι πρέπει να είναι txt αρχείο. Η εντολή do while(.not.eof(1)) είναι παρόμοια με την do i=1,n Το ".not.eof(1)" σημαίνει "not End Of File". Οπότε, με την παραπάνω εντολή ζητάμε να διαβάσει όλο το αρχείο (μέχρι να φτάσει στο τέλος του αρχείου) και να εκτελέσει τον κώδικα που έχεις γράψεις.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.