Δημοσιεύτηκε: 19 Δεκ 2011, 01:36
από kalakouentin
Νομίζω ότι διυλίζουμε τον κώνωπα... Απλά δεν ήταν ιδιαίτερα δόκιμος ως παράδειγμα, ο ελκυστής Lorentz.

Ας πέσουμε στην παράνοια όμως... Νομίζω ότι ακόμα και το αρχικό προγραμματιστικό παράδειγμα είναι τουλάχιστον "μη γενικεύσιμο". Κατηγορείς τρόπον τινά, την C για κάτι που δεν φταίει. Σε C/C++ (και σε κάθε γλώσσα προγραμματισμού) όπως είπες και εσύ σωστά, το θέμα βρίσκεται στον τρόπο αναπαράστασης/αποθήκευσης των μεταβλητών. Άρα τo να λες ότι:
lucinos έγραψε:To σφάλμα δεν οφείλεται σε κακό προγραμματισμό. Η φύση τού προβλήματος το δημιουργεί. Δεν θα μπορούσαμε να απαλλαγούμε.
είναι λάθος. Οφείλεται καθαρά σε κακό προγραμματισμό. Στην περίπτωση με τα equality relations: γιατί θεωρήθηκε ότι υπάρχει infinite αντί για finite precision arithmetic. Αυτό δεν είναι "χαοτικό" λοιπόν, απλά άθελα μας εθελοτυφλούμε.
Eίναι θέμα υλοποίησης (*) και όχι χάους. Σε τέτοια θέματα ο υπολογιστής σου είναι αρκούντως ντετερμινιστικός. Όπως προανέφερα, η ανεξήγητη συμπεριφορά ενός συστήματος δε σημαίνει πάντα ότι είναι δάκτυλος του Χάους, ίσως είναι του χρήστη...

Spoiler: show
(*)Aν υποθέσουμε ότι μιλάμε για C99, κάνοντας ένα copy-paste από το Committee Draft — Septermber 7, 2007 ISO/IEC 9899:TC3 βλέπουμε ότι η ισότητα ορίζεται ως :
§6.5.9 έγραψε:
The == (equal to) and != (not equal to) operators are analogous to the relational operators (§6.5.8) except for their lower precedence (αν έχουμε δηλαδή (a<b == c<d). Εach of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
If both of the operands have arithmetic type, the usual arithmetic conversions are performed. Values of complex types are equal if and only if both their real parts are equal and also their imaginary parts are equal. Any two values of arithmetic types from different type domains are equal if and only if the results of their conversions to the (complex) result type determined by the usual arithmetic conversions are equal.
Όπου με usual arithmetic conversion (§6.3.1.8) εννοεί το ότι (κατά σειρά προτεραιότητας) αν ένας απο τους 2 operands είναι long double, γίνεται και ο άλλος long double αλλιώς αν ένας είναι double γίνεται και ο άλλος double αλλιώς, float και ο άλλος float, κάτω από int δεν πάει (λένε κάτι για unsigned ints αλλά ντάξει λεπτομέρειες). Τα relational-operators είναι τα γνωστά ( <, >, <=, >= ), τα οποία με τη σειρά του βασίζονται στα Bitwise shift operators.
Με Βitwise οperations γίνεται η δουλειά, άρα προφανώς "ότι σώσεις, θα συγκρίνεις". :)

Στο παράδειγμα σου αν ο χρήστης ήταν αρκετά "αδαής" για να γράψει "cout << ( int(1.2 - 1. ) == int(.2))<< endl;" το όρισμα θα επέστρεφε TRUE όπως και αν έγραφε "cout << ( abs((1.2 - 1. )- (.2)) < 1e-16) << endl;" (πρακτικά γράφοντας εκτενώς το overloading που πρότεινε ο Dimitris παραπάνω). Tέλος στο ίδιο ακριβώς παράδειγμα αν γράψεις "cout << ( float(1.2 - 1. ) == float(.2))<< endl;" θα επιστρέψει και πάλι TRUE, γιατί δεν χρησιμοποίησες doubles (float: 7 bit precision, double: 15 bit precision) και μπόρεσε να κάνει το rounding ανώδυνα.

@Dimitris: ε γιορτές που είναι, διακοπές μετά από καιρό... ;)