rand#
Επιστρέφει έναν ψευδοτυχαίο αριθμό κινητής υποδιαστολής στο ημιανοικτό εύρος [0, EXPR).
Η rand αντλεί την επόμενη τιμή από τη ροή ψευδοτυχαίων αριθμών του διερμηνέα και την κλιμακώνει σε 0 <= n < EXPR. Το αποτέλεσμα είναι κανονικός αριθμός Perl (double), ποτέ ακέραιος από μόνος του - περιβάλετε με int όταν θέλετε ακέραιο αριθμό. Το EXPR είναι προαιρετικό και έχει προεπιλογή 1, οπότε η σκέτη rand επιστρέφει float στο [0, 1).
Σύνοψη#
rand EXPR
rand
Τι επιστρέφεται#
Ένα double-precision float n με 0 <= n < EXPR. Το άνω όριο είναι αποκλειστικό: η rand(6) ποτέ δεν επιστρέφει 6, μόνο τιμές αυστηρά κάτω από αυτό. Για ακέραιο αποτέλεσμα, συνδυάστε με int:
my $die = int(rand(6)) + 1; # 1..6
Η κατανομή είναι (κατά προσέγγιση) ομοιόμορφη σε όλο το εύρος. Η rand είναι βαθμωτός τελεστής - επιστρέφει μία τιμή ανά κλήση, ανεξάρτητα από το περιβάλλον.
Καθολική κατάσταση που επηρεάζει#
Η rand καταναλώνει την εσωτερική κατάσταση PRNG του διερμηνέα, την οποία μοιράζεται με την srand. Δύο κανόνες απορρέουν από αυτό:
Αυτόματη σπορά: η πρώτη κλήση της
randσε ένα πρόγραμμα καλεί αυτόματα τηνsrandαν δεν την έχετε καλέσει ήδη. Ο σπόρος επιλέγεται από εντροπία επιπέδου διεργασίας, οπότε προγράμματα χωρίς σπορά παράγουν διαφορετική ροή σε κάθε εκτέλεση.Κοινόχρηστη ροή: κάθε επόμενη κλήση
rand- οπουδήποτε στο πρόγραμμα, σε οποιοδήποτε άρθρωμα - αντλεί από την ίδια ακολουθία. Η κλήση τηςsrand($seed)με σταθερό σπόρο καθιστά αυτή την ακολουθία ντετερμινιστική και αναπαραγώγιμη, κάτι που είναι αυτό που θέλετε για test fixtures και debugging. Η κλήση τηςsrand()χωρίς όρισμα κάνει εκ νέου σπορά από εντροπία.
Δεν υπάρχει απομόνωση ανά νήμα ή ανά εμβέλεια. Αν χρειάζεστε ανεξάρτητη ροή για ένα κομμάτι κώδικα, μη χρησιμοποιήσετε την rand· καταφύγετε σε ένα ειδικό άρθρωμα γεννήτριας.
Παραδείγματα#
Βασική κλήρωση στο [0, 1):
my $u = rand(); # e.g. 0.4173...
Ρίψη ζαριού - το κανονικό ιδίωμα int(rand(N)) + 1:
my $roll = int(rand(6)) + 1; # 1..6
Τυχαίο στοιχείο πίνακα:
my @colors = qw(red green blue yellow);
my $pick = $colors[ rand @colors ];
Η rand @colors χρησιμοποιεί το μήκος του πίνακα (βαθμωτό περιβάλλον επιβαλλόμενο από το πρωτότυπο της rand), οπότε αυτό λειτουργεί για κάθε μέγεθος πίνακα.
Αναπαραγώγιμη ροή - καθορίστε τον σπόρο για τα τεστ:
srand(42);
my @sample = map { rand() } 1..5; # same five numbers every run
Μονόγραμμο ιδίωμα ανακατέματος. Ευανάγνωστο, αλλά με μεροληψία - η sort συγκρίνει ζεύγη παραπάνω από μία φορά, και μια μονομερής rand() ανά σύγκριση δεν παράγει ομοιόμορφη μετάθεση:
my @shuffled = sort { rand() <=> 0.5 } @list; # biased; do not use
Για δίκαιο ανακάτεμα, χρησιμοποιήστε την List::Util::shuffle:
use List::Util qw(shuffle);
my @shuffled = shuffle @list;
Προσομοίωση ζυγισμένου νομίσματος - σημειώστε ότι το αποκλειστικό άνω όριο σημαίνει ότι το rand() < 0.3 πυροδοτείται με πιθανότητα ακριβώς 0.3:
my $heads = rand() < 0.3 ? "heads" : "tails";
Οριακές περιπτώσεις#
Το
EXPRείναι0: αντιμετωπίζεται ως1, οπότε ηrand(0)συμπεριφέρεται όπως ηrand(1). Αυτή είναι τεκμηριωμένη συμπεριφορά του upstream και διατηρείται εδώ, αλλά είναι ιστορική ιδιορρυθμία - μη βασιστείτε σε αυτήν σε νέο κώδικα.Το
EXPRείναι αρνητικό: το αποτέλεσμα είναι απροσδιόριστο στην πράξη - μπορεί να λάβετε0, μπορεί να λάβετε αρνητικό float, και η συμπεριφορά δεν είναι φορητή μεταξύ εκδόσεων της Perl. Αν θέλετε τιμή στο[-N, 0), γράψτε ρητάrand($n) - $n.Το
EXPRείναιundef: μετατρέπεται σε"", αριθμητικοποιείται σε0, και επομένως συμπεριφέρεται όπωςrand(0)→rand(1). Υπόuse warningsλαμβάνετε προειδοποίησηuninitialized.Το
EXPRείναι μη αριθμητικό: ισχύει ο συνηθισμένος εξαναγκασμός βαθμωτού-προς-αριθμό. Ηrand("3abc")είναιrand(3)με προειδοποίηση μη αριθμητικού.Δεν είναι κρυπτογραφικά ασφαλής: η
randχρησιμοποιεί γρήγορο PRNG κατάλληλο για προσομοίωση, ανακάτεμα, και test fixtures. Δεν είναι κατάλληλη για tokens συνεδρίας, salts κωδικών, υλικό κλειδιού, ή οποιαδήποτε ευαίσθητη ως προς την ασφάλεια τιμή. Για αυτά, διαβάστε απευθείας από/dev/urandomή χρησιμοποιήστεCrypt::URandom/Crypt::PRNG.Συμπεριφορά threads/fork: μετά από
fork, γονέας και παιδί κληρονομούν την ίδια κατάσταση PRNG και θα παράγουν την ίδια ροή εκτός αν κάποιος από τους δύο καλέσει τηνsrand()για εκ νέου σπορά. Συνηθισμένη παγίδα σε pre-forking διακομιστές - κάντε σπορά στο παιδί.Μεγάλο
EXPR: η γεννήτρια παράγει 48 bits τυχαιότητας ανά κλήρωση· γιαEXPRκοντά ή πάνω από2**48, η έξοδος δεν κατανέμεται πλέον λεπτομερώς σε όλο το εύρος. Για κρυπτογραφικά πλάτη ούτως ή άλλως δεν θα έπρεπε να χρησιμοποιείτε τηνrand(δείτε παραπάνω).
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
srand- σπορά της PRNG ρητά για αναπαραγωγιμότητα, ή εκ νέου σπορά σε forked παιδίint- αποκόπτει ένα αποτέλεσμα τηςrandπρος το μηδέν για να δώσει ομοιόμορφο ακέραιο στο[0, N)List::Util::shuffle- δίκαιο ανακάτεμα Fisher-Yates· προτιμήστε αυτό αντί του ιδιώματοςsort { rand() <=> 0.5 }Crypt::URandom- κρυπτογραφικά ασφαλή τυχαία bytes από την πηγή εντροπίας του OS· χρησιμοποιήστε το για tokens, salts και υλικό κλειδιούCrypt::PRNG- κρυπτογραφικά ασφαλής PRNG με πλούσιο API όταν χρειάζεστε περισσότερα από ακατέργαστα bytes