Συζήτηση για τους τελεστές DIV και MOD

Ξεκίνησε από pfan, 04 Νοε 2003, 07:08:00 ΜΜ

« προηγούμενο - επόμενο »

pfan

Θα ήθελα να παραθέσω μια διχογνωμία σχετικά με τους τελεστές DIV και MOD.

Η πράξη -7 mod 4 δίνει αποτέλεσμα -3 όμως υπόλοιπο δεν μπορούμε να έχουμε <0 (σύμφωνα με την ευκλείδεια διαίρεση). Σε ένα βιβλίο για την Pascal (Κάβουρας) που μου υπέδειξε ένας συνάδελφος διάβασα ότι στην τυποποιημένη pascal η πράξη -7 mod 4 δίνει αποτέλεσμα 1. Επίσης εκεί διάβασα ότι δεν μπορώ να έχω αρνητικό διαιρέτη με την mod.
Κατάλαβα επομένως ότι σε άλλες υλοποιήσεις τις Pascal μπορώ να έχω αρνητικό υπόλοιπο και να χρησιμοποιώ αρνητικό διαιρέτη (γιατί στην ουσία κάνει συνεχείς αφαιρέσεις του διαιρέτη με τον διαιρετέο) ενώ στην τυποποιημένη όχι.

Το ερώτημα μου είναι το εξής αν στο τέλος βάλουν θέμα παρόμοιο με αυτό των επαναληπτικών του 2002

Να υπολογίσετε την τιμή της αριθμητικής έκφρασης
Β *(A DIV B)+(A MOD B)
Για τις παρακάτω περιπτώσεις:
i) Α=10 ΚΑΙ Β= 5
ii) Α=-5 ΚΑΙ Β= 1
ii) Α=1 ΚΑΙ Β= 5
(σε αυτό το θέμα δεν υπήρχε πρόβλημα γιατί -5 mod 1=0 επίσης είναι φανερό ότι η παράσταση αυτή θα δίνει πάντα ως αποτέλεσμα την τιμή του Α)

Αν όμως για νούμερα δώσουν -7 mod 4 ή -80 mod -30 ή 15 mod -6 o μαθητής τι θα πρέπει να απαντήσει;

Αν και πιστεύω ότι είναι δύσκολο να βάλουν τέτοιο θέμα δεν το θεωρώ απίθανο.
Πύρζα Φανή
Καθηγήτρια Πληροφορικής

Sergio

#1
Οπως σε όλες τις γλώσσες (πχ. Pascal που φέρνεις για παράδειγμα), έτσι και στη ΓΛΩΣΣΑ των συγγραφέων, η μόνη σαφής και πλήρης απάντηση μπορεί να έρθει από τον ορισμό της ΓΛΩΣΣΑς.

Δυστυχώς το βιβλίο δεν ορίζει τους τελεστές div και mod με τρόπο που να επιτρέπει μονοσήμαντη απάντηση στο ερώτημά σου Φανή.

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

Οι μαθητές της Β' Λυκείου διδάσκονται τον τελεστή mod στα πλαίσια του μαθήματος "Μαθηματικά Κατεύθυνσης".

Εκεί, ο τελεστής mod δίνει πάντα ΘΕΤΙΚΟ αποτέλεσμα.

Το πηλίκο της ακέραιας διαίρεσης (δηλ. το αποτέλεσμα της div για εμάς) ανάμεσα σε ετερόσημους τελεστέους, είναι αρνητικό, και κατ'απόλυτη τιμή αυξημένο κατά 1 (όταν η διαίρεση δεν είναι τέλεια), σε σχέση με το πηλίκο που δίνει η ευκλείδια διαίρεση των απόλυτων τιμών των τελεστέων.

Με απλά λόγια:
-7 DIV 4 = -(|7| DIV |4| + 1) = -(1 + 1) = -2
επομένως
-7 MOD 4 = -7 -(4 * (-7 DIV 4) ) = -7 - (4 * (-2) ) = -7 -(-8 ) = -7 + 8 = 1

Αν λοιπόν δεχτούμε ότι οι μαθητές οφείλουν να σκεφτούν (από μαθηματικής πλευράς) με τον τρόπο που ξέρουν, τότε:
-7 DIV 4 = -2
&
-7 MOD 4 = 1

βλ.και τα παραδείγματα της σελίδας 142 του βιβλίου Μαθηματικών κατεύθυνσης της Β' Λυκείου
Απ τη μια η θητεία μου σε σχολικές αίθουσες: να φλυαρώ - να ελπίζω πως κατι κατάλαβαν - να εξερευνώ - να μαθαίνω. Απ την άλλη, σχεδόν συνομήλικη, η Διδακτική της Πληροφορικής: ερευνά διαδικασίες μάθησης - φλερτάρει με την Ψυχολογία - με καλεί να αφήσω το βλέμμα του Πληροφορικού και να δω με τα μάτια του δασκάλου. Τέκνα των 2, οι απόψεις μου.. (προσαρμοσμένο από τον πρόλογο του βιβλίου "Το μακρόν Φυσική προ του βραχέως διδάσκω" του Ανδρέα Κασσέτα)

bugman

#2
-7 mod 4 δίνει -3
Οι γλώσσες προγραμματισμού δεν είναι μαθηματικά!δηλαδή το - θα δουλέψει στο τέλος. Πρώτα θα γίνει το 7 mod 4 που θα δώσει το 3 και μετά θα δώσει το - το -3.
Το - λέγετε μοναδιαίος τελεστής.

Το γιατί μια γλώσσα δίνει στο - 7 mod 4 το 1 μπορεί να εξηγηθεί.
Η εξήγηση είναι στο τι λέμε sign και τι unsign ακέραιο.
το -7 σε περίπτωση unsign ακεραίου θα καταχωρηθεί (για ακέραιο μεγέθους ένα byte) ως 256-7, άρα 249, και η πράξη θα γίνει ως 249 mod 4 που δίνει 1

(για ακέραιο unsign ενός word το -7 θα γραφτεί ως 65529 (256*256-7) και το 65529 mod 4 δίνει πάλι 1.

Η αριθμητική των υπολογιστών είναι απλή αριθμητική δημοτικού! (Γιαυτό την καταλαβαίνω! :-[ )


Η M2000 εκτελεί τον παρακάτω κώδικα, στο τμήμα του evaluator  (ελέγχει πιο πριν και για διαίρεση με το μηδέν):
po = Sgn(r1) * (Int(Abs(r1)) - Int(Int(Abs(r1) / Abs(Int(po))) * Abs(Int(po))))
  
όπου στην πράξη - 7 mod 4 το r1=-7 και το po=4, τα r1 και p1 είναι πραγματικοί αριθμοί (τεράστιοι :))

alkisg

#3
Ο μοναδιαίος τελεστής (-) σε πολλές γλώσσες προγραμματισμού έχει μεγαλύτερη προτεραιότητα από τον δυαδικό (-). Παράδειγμα από την Basic (περίπου τα ίδια ισχύουν και στον διερμηνευτή, για την ΓΛΩΣΣΑ είναι υπό συζήτηση, αν καταλήξουμε σε διαφορετικό συμπέρασμα τροποποιώ κατάλληλα και τον διερμηνευτή):

+------------------------------------+-------------------------------+---------+
|                            Προτεραιότητα Basic                               |
+------------------------------------+-------------------------------+---------+
| Arithmetic                         | Comparison                    | Logical |
+------------------------------------+-------------------------------+---------+
| Exponentiation (^)                 | Equality (=)                  | Not     |
| Negation (-)                       | Inequality (<>)               | And     |
| Multiplication and division (*, /) | Less than (<)                 | Or      |
| Integer division (\)               | Greater than (>)              | Xor     |
| Modulus arithmetic (Mod)           | Less than or equal to (<=)    | Eqv     |
| Addition and subtraction (+, -)    | Greater than or equal to (>=) | Imp     |
| String concatenation (&)           | Like                          |         |
|                                    | Is                            |         |
+------------------------------------+-------------------------------+---------+

Δηλαδή το -7 div 4 αποτιμάται ως (-7) div 4. Αντίστοιχα, επειδή η δύναμη έχει μεγαλύτερη προτεραιότητα από το πρόσημο (-) το -2^2 αποτιμάται ως -(2^2).

bugman

Άλκη, πες με παράξενο, αλλά βλέπω ότιπιάνεις το θέμα επιφανειακά!
ας πούμε αυτό:
η παράσταση 3*5+2^5 με της προτεραιότητες που λες μπορεί να κάνει κάποιον να σκεφθεί ότι το 2^5 θα γίνει πιο μπροστά από το 3*5. Αλλά δεν πρόκειται να γίνει έτσι!
Όσο για το σχολείο, για την ΓΛΩΣΣΑ επιτέλους οι καθηγητές να  φτιάξουν έναν πρότυπο εκτιμητή (evaluator, αν θες πές το αλλιώς Άλκη), ο οποίος θα είναι ένα πρόγραμμα στο οποίο:
1. Θα δηλώνουμε μεταβλητές.
2. Θα περνάμε τιμές.
3. Θα εκτελούμε μια παράσταση.

Ας το δώσουν σε κάποιον σπουδαστή τους να το φτιάξει.

Θα είναι ένα πρόγραμμα αναφοράς.

Και ο μεταφραστής σου (διότι έτσι λέω τους interpreters εγώ) θα μπορούσε να γίνει σημείο αναφοράς. (Πούλα τον στο Υπουργείο)




alkisg

Οκ Γιώργο, θα σε πω παράξενο ;) επειδή νομίζω ότι αν μια γλώσσα δηλώνει ξεκάθαρα σε πινακάκι τις προτεραιότητες αυτό δεν έχει τίποτα επιφανειακό!!!
Απλά δεν έχει από κάτω την υποσημείωση ότι τα τελούμενα αποτιμούνται left - to - right (ήταν σε άλλο σημείο του help file): το 3*5 είναι το πρώτο τελούμενο του τελεστή + και αποτιμάται πριν από το δεύτερο τελούμενο που είναι το 2^5. Αν και ΟΛΟΙ οι compilers που κάνουν optimization ΔΕΝ ΕΓΓΥΟΥΝΤΑΙ σειρά αποτίμησης τελουμένων (ούτε εκφράσεων - παραμέτρων σε υποπρογράμματα) για να μπορέσουν να κάνουν καλύτερη βελτιστοποίηση σε σχέση με το τελικό μέγεθος και την ταχύτητα εκτέλεσης του προγράμματος.
Όλα αυτά βέβαια δεν έχουν καμία απολύτως σχέση με την προτεραιότητα των τελεστών, η οποία ισχύει πάντα όπως ορίζεται από τα αντίστοιχα πινακάκια ή τα BNF των γλωσσών προγραμματισμού.

(δεν πιστεύω να παρεξηγήθηκες για το "παράξενος", για αστείο το έγραψα).

bugman

Ένας τρόπος να διαπιστώσει κανείς την σειρά των πράξεων θα ήταν ο εξής:
Φτιάχνουμε μια συνάρτηση Φ(χ). Η συνάρτηση αυτή θα μπορεί να "βλεέπει" έναν πίνακα και να βάζει νούμερα σε όποια θέση θέλουμε.
Η θέση θα είναι αυτόματα αυξανόμενη κατά 2 και θα ξεκινάει από το 1. Υποθέτουμε ότι ο πίνακας μπορεί να έχει εκατό τουλάχιστον στοιχεία.
Φτιάχνουμε μια αριθμητική παράσταση και όπου βάζαμε "αριθμό" θα βάλουμε την συνάρτηση με παράμετρο ένα νούμερο, το νούμερο που θέλουμε για την θέση του "αριθμού". Η συνάρτηση θα γυρνάει ένα τυχαίο νούμερο - μη μηδενικό.
Έτσι μετά το πέρας εκτέλεσης της αριθμητικής παράστασης θα έχουμε έναν πίνακα με την σειρά των θέσεων που πρώτα εκτιμήθηκαν.