Το Στέκι των Πληροφορικών

Γενικά => Γενικά Παιδαγωγικά, Επιστημονικά και Τεχνικά Θέματα => Επιστημονικά Θέματα => Μήνυμα ξεκίνησε από: kamer στις 05 Σεπ 2010, 06:22:43 μμ

Τίτλος: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 05 Σεπ 2010, 06:22:43 μμ
Προσπάθησα να φτίαξω στην ψευδογλώσσα ενα πρόγραμμα που να βρίσκει τέλειους αριθμούς
Τέλειοι αριθμοί ονομάζονται αυτοί που το άθροισμα των διαιρετών τους είναι ίσο με τον ίδιο τον αριθμό (π.χ. 6, 28, 496...)
Ο τύπος για να βρεθούν αυτοί οι αριθμοί ειναι (2^(χ-1))*((2^χ)-1) με την προϋπόθεση ότι το χ και το (2^χ)-1 είναι πρώτοι.
Έχει ένα πρόβλημα με την εντολη mod. Καθώς εξ' ορισμού το (2^χ)-1 είναιπραγματική έκφραση δεν μπορεί να εφαρμοστεί η προαναφερθείσα εντολή.
Μπορείτε να μου προσφέρετε κάποια λύση;
Σας παραθέτω το πρόγραμμα από κάτω ωστε αν μπορεί κάποιος να με βοηθήσε

ΠΡΟΓΡΑΜΜΑ ΤΕΛΕΙΟΙ_ΑΡΙΘΜΟΙ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: χ, πλήθος_διαιρετών, διαιρέτης
  ΠΡΑΓΜΑΤΙΚΕΣ: βπρωτος, τελειος
ΑΡΧΗ
  χ <- 2
  τελειος <- 2^(χ - 1)*((2^χ) - 1)
  ΓΡΑΨΕ τελειος
  χ <- 3
  ΟΣΟ χ <= 99 ΕΠΑΝΑΛΑΒΕ
    πλήθος_διαιρετών <- 0
    διαιρέτης <- 2
    ΑΝ χ MOD διαιρέτης = 0 ΤΟΤΕ
      πλήθος_διαιρετών <- πλήθος_διαιρετών + 1
    ΑΛΛΙΩΣ
      διαιρέτης <- διαιρέτης + 1
    ΤΕΛΟΣ_ΑΝ
    ΟΣΟ πλήθος_διαιρετών < 1 ΚΑΙ διαιρέτης <= χ DIV 2 ΕΠΑΝΑΛΑΒΕ
      ΑΝ χ MOD διαιρέτης = 0 ΤΟΤΕ
        πλήθος_διαιρετών <- πλήθος_διαιρετών + 1
      ΑΛΛΙΩΣ
        διαιρέτης <- διαιρέτης + 2
      ΤΕΛΟΣ_ΑΝ
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ΑΝ πλήθος_διαιρετών < 1 ΤΟΤΕ
      βπρωτος <- 2^χ - 1
      πλήθος_διαιρετών <- 0
      διαιρέτης <- 2
      ΑΝ βπρωτος MOD διαιρέτης = 0 ΤΟΤΕ
        πλήθος_διαιρετών <- πλήθος_διαιρετών + 1
      ΑΛΛΙΩΣ
        διαιρέτης <- διαιρέτης + 1
      ΤΕΛΟΣ_ΑΝ
      ΟΣΟ πλήθος_διαιρετών < 1 ΚΑΙ διαιρέτης <= βπρωτος DIV 2 ΕΠΑΝΑΛΑΒΕ
        ΑΝ βπρωτος MOD διαιρέτης = 0 ΤΟΤΕ
          πλήθος_διαιρετών <- πλήθος_διαιρετών + 1
        ΑΛΛΙΩΣ
          διαιρέτης <- διαιρέτης + 2
        ΤΕΛΟΣ_ΑΝ
      ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
      ΑΝ πλήθος_διαιρετών < 1 ΤΟΤΕ
        τελειος <- (2^χ)*((2^χ) - 1)
        ΓΡΑΨΕ τελειος
      ΤΕΛΟΣ_ΑΝ
      χ <- χ + 2
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ ι
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: sstergou στις 05 Σεπ 2010, 06:40:11 μμ
Το πρόβλημα υφίσταται στην ΓΛΩΣΣΑ. Στην ψευδογλώσσα που είναι πιο χαλαρά τα πράγματα δεν υπάρχει τέτοιο θέμα.

Μια ιδέα είναι να δηλώσεις το τελειος ως ακέραια μεταβλητή και στην επίμαχη εκχώρηση να χρησιμοποιήσεις την συνάρτηση Α_Μ που επιστρέφει το ακέραιο μέρος ενός πραγματικού αριθμού, δηλ : τέλειος <- Α_Μ(2^(χ-1)*(2^χ)-1)).
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 05 Σεπ 2010, 06:47:54 μμ
Η πρότασή σου δούλεψε
τώρα τρέχει υπέροχα
Το μόνο που χρειάζεται είναι να βελτιώσω την αποδοτικότητα του προγράμματος
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 05 Σεπ 2010, 07:32:06 μμ
Τελικά το Α_Μ χρειαζόταν μετά από το βπρωτος
Για κάποιο λόγο όταν το έβαζα μετά από το τελειος έφερνε πίσω μερικές φορές λάθος αποτελέσματα

Το πρόγραμμα τώρα είναι ως εξής

ΠΡΟΓΡΑΜΜΑ ΤΕΛΕΙΟΙ_ΑΡΙΘΜΟΙ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: χ, απλήθος_διαιρετών, διαιρέτης, βπρωτος, βπλήθος_διαιρετών
  ΠΡΑΓΜΑΤΙΚΕΣ: τελειος
ΑΡΧΗ
  χ <- 2
  τελειος <- (2^(χ - 1)*((2^χ) - 1))
  ΓΡΑΨΕ τελειος
  χ <- 3
  ΟΣΟ χ <= 99 ΕΠΑΝΑΛΑΒΕ
    απλήθος_διαιρετών <- 0
    διαιρέτης <- 2
    ΑΝ χ MOD διαιρέτης = 0 ΤΟΤΕ
      απλήθος_διαιρετών <- απλήθος_διαιρετών + 1
    ΑΛΛΙΩΣ
      διαιρέτης <- διαιρέτης + 1
    ΤΕΛΟΣ_ΑΝ
    ΟΣΟ απλήθος_διαιρετών < 1 ΚΑΙ διαιρέτης <= χ DIV 2 ΕΠΑΝΑΛΑΒΕ
      ΑΝ χ MOD διαιρέτης = 0 ΤΟΤΕ
        απλήθος_διαιρετών <- απλήθος_διαιρετών + 1
      ΑΛΛΙΩΣ
        διαιρέτης <- διαιρέτης + 2
      ΤΕΛΟΣ_ΑΝ
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ΑΝ απλήθος_διαιρετών < 1 ΤΟΤΕ
      βπρωτος <- Α_Μ(2^χ - 1)
      βπλήθος_διαιρετών <- 0
      διαιρέτης <- 2
      ΑΝ βπρωτος MOD διαιρέτης = 0 ΤΟΤΕ
        βπλήθος_διαιρετών <- βπλήθος_διαιρετών + 1
      ΑΛΛΙΩΣ
        διαιρέτης <- διαιρέτης + 1
      ΤΕΛΟΣ_ΑΝ
      ΟΣΟ βπλήθος_διαιρετών < 1 ΚΑΙ διαιρέτης <= βπρωτος DIV 2 ΕΠΑΝΑΛΑΒΕ
        ΑΝ βπρωτος MOD διαιρέτης = 0 ΤΟΤΕ
          βπλήθος_διαιρετών <- βπλήθος_διαιρετών + 1
        ΑΛΛΙΩΣ
          διαιρέτης <- διαιρέτης + 2
        ΤΕΛΟΣ_ΑΝ
      ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
      ΑΝ βπλήθος_διαιρετών < 1 ΤΟΤΕ
        τελειος <- ((2^(χ - 1))*((2^χ) - 1))
        ΓΡΑΨΕ τελειος
        χ <- χ + 2
      ΑΛΛΙΩΣ
        χ <- χ + 2
      ΤΕΛΟΣ_ΑΝ
    ΑΛΛΙΩΣ
      χ <- χ + 2
    ΤΕΛΟΣ_ΑΝ
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 07 Σεπ 2010, 03:45:22 μμ
Όταν βάζω την ΓΛΩΣΣΑ να εκτελέσει το παρακάτω πρόγραμμα βγάζει λάθος αποτελέσματα.

ΠΡΟΓΡΑΜΜΑ δοκιμη
ΜΕΤΑΒΛΗΤΕΣ
  ΠΡΑΓΜΑΤΙΚΕΣ: ν
ΑΡΧΗ
  ν <- 2^37 - 1
  ΓΡΑΨΕ ν
  ν <- Α_Μ(ν)
  ΓΡΑΨΕ ν
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

Ξέρει κανείς γιατί????
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Keep Growing στις 07 Σεπ 2010, 04:01:59 μμ
μέχρι το 2^31 δουλεύει καλά.
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: alkisg στις 07 Σεπ 2010, 05:35:10 μμ
Γενικά ο Διερμηνευτής υποστηρίζει 64-bit ακεραίους (https://alkisg.mysch.gr/%CE%93%CE%9B%CE%A9%CE%A3%CE%A3%CE%91/%CE%A4%CF%8D%CF%80%CE%BF%CE%B9_%CE%B4%CE%B5%CE%B4%CE%BF%CE%BC%CE%AD%CE%BD%CF%89%CE%BD/), ακόμα και σε 32-bit συστήματα. Έτσι τα όρια των ακεραίων είναι τα ±2^63.
Ειδικά όμως για το ακέραιο μέρος Α_Μ, χρησιμοποιεί αναγκαστικά τη συνάρτηση Floor (http://docwiki.embarcadero.com/VCL/en/Math.Floor) του Delphi, κι έτσι εκεί περιορίζεται σε 32-bit ακεραίους, δηλαδή ±2^31.

Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 07 Σεπ 2010, 05:50:22 μμ
Άμα είναι παραπάνω βγάζει λάθος αποτέλεσμα. . .  όπως για παράδειγμα -1 :'(
Υπάρχει κάποια ιδέα για το πως να προχωρήσω πέρα από το 8ο αποτέλεσμα σε αυτόν τον αλγόριθμο???

ΠΡΟΓΡΑΜΜΑ ΤΕΛΕΙΟΙ_ΑΡΙΘΜΟΙ
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: χ, απλήθος_διαιρετών, διαιρέτης, βπρωτος, βπλήθος_διαιρετών
  ΠΡΑΓΜΑΤΙΚΕΣ: τελειος
ΑΡΧΗ
  χ <- 2
  τελειος <- (2^(χ - 1)*((2^χ) - 1))
  ΓΡΑΨΕ τελειος
  χ <- 3
  ΟΣΟ χ <= 99 ΕΠΑΝΑΛΑΒΕ
    απλήθος_διαιρετών <- 0
    διαιρέτης <- 2
    ΑΝ χ MOD διαιρέτης = 0 ΤΟΤΕ
      απλήθος_διαιρετών <- απλήθος_διαιρετών + 1
    ΑΛΛΙΩΣ
      διαιρέτης <- διαιρέτης + 1
    ΤΕΛΟΣ_ΑΝ
    ΟΣΟ απλήθος_διαιρετών < 1 ΚΑΙ διαιρέτης <= Α_Μ(χ^(1/2)) ΕΠΑΝΑΛΑΒΕ
      ΑΝ χ MOD διαιρέτης = 0 ΤΟΤΕ
        απλήθος_διαιρετών <- απλήθος_διαιρετών + 1
      ΑΛΛΙΩΣ
        διαιρέτης <- διαιρέτης + 2
      ΤΕΛΟΣ_ΑΝ
    ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
    ΑΝ απλήθος_διαιρετών < 1 ΤΟΤΕ
      βπρωτος <- Α_Μ(2^χ - 1)
      βπλήθος_διαιρετών <- 0
      διαιρέτης <- 2
      ΑΝ βπρωτος MOD διαιρέτης = 0 ΤΟΤΕ
        βπλήθος_διαιρετών <- βπλήθος_διαιρετών + 1
      ΑΛΛΙΩΣ
        διαιρέτης <- διαιρέτης + 1
      ΤΕΛΟΣ_ΑΝ
      ΟΣΟ βπλήθος_διαιρετών < 1 ΚΑΙ διαιρέτης <= Α_Μ(βπρωτος^(1/2)) ΕΠΑΝΑΛΑΒΕ
        ΑΝ βπρωτος MOD διαιρέτης = 0 ΤΟΤΕ
          βπλήθος_διαιρετών <- βπλήθος_διαιρετών + 1
        ΑΛΛΙΩΣ
          διαιρέτης <- διαιρέτης + 2
        ΤΕΛΟΣ_ΑΝ
      ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
      ΑΝ βπλήθος_διαιρετών < 1 ΤΟΤΕ
        τελειος <- 2^(χ - 1)*((2^χ) - 1)
        ΓΡΑΨΕ τελειος
        χ <- χ + 2
      ΑΛΛΙΩΣ
        χ <- χ + 2
      ΤΕΛΟΣ_ΑΝ
    ΑΛΛΙΩΣ
      χ <- χ + 2
    ΤΕΛΟΣ_ΑΝ
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Keep Growing στις 08 Σεπ 2010, 12:01:23 πμ
Αν πας, στη Γλώσσα, στο μενού Εργαλεία -> Επιλογές -> ασάφειες και ζητήσεις στην συνάρτηση Α_Μ() να χρησιμοποιείται ο ορισμός της Πληροφορικής, τότε μπορεί να φτάσεις και μέχρι το 2^49 για μη επιστημονική γραφή του αριθμού και 2^62 για επιστημονική γραφή του αριθμού.  :D

Αν θέλεις πάλι, μπορείς να φτιάξεις εσύ μια συνάρτηση Α_Μ() σύμφωνα με την γενική μορφή της απεικόνισης στο δεκαδικό σύστημα.
Δες στον παρακάτω σύνδεσμο:
http://spinet.gr/glossomatheia/programs/viewtopic.php?f=6&t=722&view=previous

Παντού και πάντα όμως θα βρίσκεις φραγμούς. Το μόνο πράγμα που δεν έχει φραγμούς είναι η φαντασία μας.  :)
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Νίκος Αδαμόπουλος στις 08 Σεπ 2010, 11:21:32 πμ
Αν το ζητούμενο είναι να εντοπιστούν όσο το δυνατό περισσότεροι τέλειοι αριθμοί, τότε ίσως πρέπει να επιλεχθεί κάποια άλλη γλώσσα προγραμματισμού πιο κατάλληλη για κάτι τέτοιο... αλλά και να εφαρμοστούν τεχνικές οι οποίες θα ξεπερνούν τους περιορισμούς που κάθε γλώσσα έχει...

Η ΓΛΩΣΣΑ έχει δημιουργηθεί μόνο για εκπαιδευτικούς σκοπούς και για εισαγωγή στον προγραμματισμό... Μάλιστα δεν έχει ούτε καν οριστεί πλήρως ή και με την απαιτούμενη σαφήνεια... Π.χ. δεν έχουν καθοριστεί τα όρια των αριθμών που θα μπορεί να διαχειρίζεται, κάτι που είναι από τα πρώτα που ορίζονται σε κάποια κανονική γλώσσα προγραμματισμού...
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 09 Σεπ 2010, 03:56:42 μμ
Με την προηγούμενη πρόταση πράγματι εξαφανιστηκε το λάθος (αν και παραμένουν άλλα τα οποία ίσως και να μην γίνετε να επιλυθούν).
Όσων αναφορά την δεύτερη πρόταση είναι κάπως δύσκολο καθώς δεν γνωρίζω κάποια άλλη γλώσσα προγραμματισμου :-\
Τέλος, οι ενναλακτικοί αλγόριθμοι για το ακέραιο μέρος περιέχουν όλοι ένα μαθηματικό λάθος. Α_Μ(-123.54)=-124 και όχι -123 όπως βγάζει
Ίσως κάποιος ο οποίος έχει λογαριασμό στο site που αναφέρθηκε να μπορεί να το διορθώσει
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Keep Growing στις 09 Σεπ 2010, 04:16:05 μμ
...Δεν είναι λάθος ακριβώς. Δες παρακάτω μια συζήτηση για το θέμα.

https://alkisg.mysch.gr/steki/index.php?topic=928.0
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Νίκος Αδαμόπουλος στις 09 Σεπ 2010, 07:45:39 μμ
Αν πας, στη Γλώσσα, στο μενού Εργαλεία -> Επιλογές -> ασάφειες και ζητήσεις στην συνάρτηση Α_Μ() να χρησιμοποιείται ο ορισμός της Πληροφορικής ...

Το έχεις κάνει αυτό;
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Keep Growing στις 09 Σεπ 2010, 08:08:29 μμ
Ναι, Νίκο, το δοκίμασα.
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Νίκος Αδαμόπουλος στις 09 Σεπ 2010, 09:03:25 μμ
... τον kamer εννοούσα...! Αν αλλάξει τη ρύθμιση δεν θα έχει πρόβλημα με το ΑΜ...
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: Keep Growing στις 09 Σεπ 2010, 09:33:03 μμ
Το φαντάστηκα, αλλά καθυστερημένα.
Τίτλος: Απ: Μπορεί κάποιος να με βοηθήσει???
Αποστολή από: kamer στις 10 Σεπ 2010, 10:04:36 πμ
Μετά από την πρόταση του keep growing το δοκίμασα και δούλεψε, αν και πλέον οι αριθμοί ήταν τόσο μεγάλοι που το πρόγραμμα ούτως η άλλως δεν μπορούσε να τους χειριστεί. Πάντως θέλω να σας ευχαριστήσω όλους για την βοήθεια που μου δώσατε. Το ίδιο το πρόγραμμα που έφτιαξα δεν είναι σημαντικο, αλλά όσα έμαθα φτιαχνοντάς το ήταν πολύ ωραιά και πολύ ενδιαφέροντα. :)