Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

"Comparing floating point quantities for equality may give misleading results" στιις γραμμες 7 και 8.

Αφού κάνω compile το πρόγραμμα, μου βγάζει την από πάνω προειδοποίηση. Πρέπει να αλλάξω κάτι? Αν μπορεί κανεις ας του ρίξει μια ματιά, ευχαριστώ :)

 

 

 

 

program Eksiswsh
implicit none
real :: a,b,x
print*, "ax^2+b=0"
10 print*, "a=" ; read*, a
print*, "b=" ; read*, b
if (a==0) then
  if (b==0) then
    print*, "aoristh"
    else
    print*, "adynath"
      end if
      else
        if (((-b)/a)>=0) then
          x=sqrt((-b)/a)
          print*, "x=", x,-x
          else
            print*, "adynath"
            end if
            end if
            goto 10
            end program

Δημοσ.

Ίσως είναι γιατί εχεις δηλώσει τις a και b ως float και τις συγκρίνεις με integer (με "0" αντί για "0.0") αλλά το πιο πιθανό είναι ότι στο λέει γιατί η σύγκριση δύο floats είναι περίεργη υπόθεση. Το θέμα είναι μεγάλο αλλά αν σε ενδιαφέρει δες αυτά

 

http://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/

http://floating-point-gui.de/errors/comparison/

 

Fortran έχω να δω πολλά χρόνια, αλλά στην συγκεκριμένη περίπτωση, εκτός και αν σκόπευα να δώσω τεράστιες ή μικροσκοπικές τιμές στα α και β. εγώ θα το αγνοούσα μάλλον.

 

Πιθανότατα ο compiler θα έχει κάποιο flag για να το κάνει supress.

 

edit

Εν ολίγοις, μια καλύτερη τακτική αντί να συγκρίνεις για ισότητα δύο floats είναι να ελέγχεις αν η διαφορά τους είναι μικρότερη από μία ποσότητα που το μέγεθος της θα το ορίζεις ανάλογα με το πρόβλημα σου. Πχ για τους float a, b αντί για

if a == b:
    ...
γράφεις
abs(a -  <= tol:
    ...
αν οι a και b είναι integers δεν υπάρχουν τέτοια προβλήματα. Αν διαβάσεις τα παραπάνω links θα δεις ότι δυστυχώς το όλο θέμα είναι πολύ πιο περίπλοκο από όσο φαίνεται.
Δημοσ.

Υπάρχουν 2 τρόποι να προσεγγίσει κανείς το θέμα που αντιμετωπίζεις.

 

1. Ο θεωρητικός: όταν προσπαθείς να αναπαραστήσεις έναν πραγματικό αριθμό ως μία 32-μπιτη ή 64-μπιτη ή [οσοθελεις]-μπιτη τιμή, είναι δεδομένο ότι δε μπορείς παρά να έχεις πεπερασμένη ακρίβεια. Άρα, εκτελώντας στον κώδικά σου πράξεις με αυτές τις αναπαραστάσεις, ενδέχεται συνεχώς να εισάγεις επιπλέον σφάλμα. Γι' αυτό και ο compiler που χρησιμοποιείς (και όχι μόνο αυτός), όταν ανιχνεύσει στον κώδικά σου απόπειρα ελέγχου ισότητας μεταξύ αναπαραστάσεων πραγματικών αριθμών, σε προειδοποιεί για το ενδεχόμενο να συμβεί το εξής: ο κώδικάς σου σε κάποιο συγκεκριμένο σενάριο εκτέλεσης να προβλέπει θεωρητικά ισότητα, αλλά η πεπερασμένης ακρίβειας αναπαραστάσεις να μην προκύπτουν με ίδια ακριβώς τιμή (λόγω των σφαλμάτων).

 

2. Ο πρακτικός: Οι δύο μεταβλητές που χρησιμοποιείς εισάγονται από τον χρήστη και πριν να τις συγκρίνεις για ισότητα, δεν τους εκχωρείς νέα τιμή που προκύπτει από την παλιά μέσω πράξεων. Oπότε, κλάην μάην. :D

 

 

F@ck, με πρόλαβαν...

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...