Αριθμητικές συναρτήσεις

int#

Επιστρέφει το ακέραιο μέρος ενός αριθμού, με αποκοπή προς το μηδέν.

Η int παίρνει ένα βαθμωτό, το εξαναγκάζει σε αριθμητικό περιβάλλον, και απορρίπτει το κλασματικό του μέρος. Η απόρριψη γίνεται πάντα προς το μηδέν - όχι προς το αρνητικό άπειρο - οπότε η int(3.9) δίνει 3 και η int(-3.9) δίνει -3, όχι -4. Οι μη αριθμητικές συμβολοσειρές εξαναγκάζονται με τους συνήθεις κανόνες αριθμητικής μετατροπής της Perl (αρχικά κενά, προαιρετικό πρόσημο, ψηφία· το υπόλοιπο απορρίπτεται, με προειδοποίηση Argument "..." isn't numeric υπό use warnings). Αν παραλειφθεί το EXPR, η int λειτουργεί στο $_.

Σύνοψη#

int EXPR
int
int($x)

Τι επιστρέφεται#

Ένας αριθμός χωρίς κλασματικό μέρος, με το ίδιο πρόσημο με την είσοδο. Το αποτέλεσμα είναι ακέραια τιμή αν το αποκομμένο μέτρο χωρά στο εγγενές εύρος ακεραίων της πλατφόρμας (τυπικά 64-bit)· διαφορετικά η Perl το διατηρεί ως τιμή κινητής υποδιαστολής της οποίας το κλασματικό μέρος τυχαίνει να είναι μηδέν. Σε κάθε περίπτωση συγκρίνεται και εκτυπώνεται ως ακέραιος.

my $n = int(7.8);          # 7
my $m = int(-7.8);         # -7

Η int δεν είναι συνάρτηση στρογγυλοποίησης. Για στρογγυλοποίηση, δείτε Δείτε επίσης.

Παραδείγματα#

Αποκοπή θετικού - το κλασματικό μέρος απορρίπτεται:

print int(3.9), "\n";               # 3
print int(3.1), "\n";               # 3
print int(3.0), "\n";               # 3

Αποκοπή αρνητικού - η παγίδα. Η int αποκόπτει προς το μηδέν, οπότε η int(-3.9) είναι -3, που είναι μεγαλύτερο από -3.9. Αυτό είναι το αντίθετο της μαθηματικής floor:

print int(-3.9), "\n";              # -3   (not -4)
print int(-3.1), "\n";              # -3

Λειτουργεί στο $_ όταν καλείται χωρίς ορίσματα - χρήσιμο μέσα σε map ή while (<>):

my @whole = map { int } @floats;    # truncate every element

Οι συμβολοσειρές εξαναγκάζονται, διατηρώντας το αρχικό αριθμητικό πρόθεμα:

print int("42.7 bottles"), "\n";    # 42
print int("  -5.5xyz"), "\n";       # -5
print int("hello"), "\n";           # 0    (with a warning under `use warnings`)

Διαίρεση που παράγει κλάσμα, μετά αποκόπτεται - συνηθισμένο ιδίωμα για ακέραια διαίρεση προσημασμένων τιμών, με την παραπάνω επιφύλαξη για τα αρνητικά:

my $pages = int($total_items / $per_page);   # floor only for non-negative $total_items

Η κλασική έκπληξη της κινητής υποδιαστολής. Το -6.725 / 0.025 είναι μαθηματικά -269, αλλά το αποτέλεσμα κατά IEEE-754 είναι ελαφρώς μεγαλύτερο από -269 (περίπου -268.99999999999994). Η int αποκόπτει προς το μηδέν, δίνοντας -268:

print int(-6.725 / 0.025), "\n";    # -268, not -269

Αυτό δεν είναι bug της int - κάθε συνάρτηση αποκοπής/στρογγυλοποίησης πρέπει να αντιμετωπίσει εισόδους όπως αυτή. Δείτε Οριακές περιπτώσεις παρακάτω.

Οριακές περιπτώσεις#

  • Η int στο $_: χωρίς όρισμα, λειτουργεί στο $_. Μέσα σε map { int } αυτό είναι που θέλετε· μέσα σε μεγαλύτερη έκφραση μπορεί να ξαφνιάσει αναγνώστη που έχασε το σιωπηρό όρισμα. Προτιμήστε int($x) όταν η μεταβλητή πηγής δεν είναι προφανής από το συγκείμενο.

  • Είσοδος που είναι ήδη ακέραιος: η int(5) δίνει 5. Καμία μετατροπή, καμία προειδοποίηση, καμία απώλεια ακρίβειας.

  • Οι πολύ μεγάλοι αριθμοί κινητής υποδιαστολής χάνουν ακρίβεια πριν τους δει η int. Ένας αριθμός κινητής υποδιαστολής διπλής ακρίβειας μπορεί να αναπαραστήσει επακριβώς κάθε ακέραιο έως το 2**53· πέρα από αυτό, διαδοχικές αναπαραστάσιμες τιμές απέχουν 2, μετά 4, μετά 8. Η int(1e20) επιστρέφει αριθμό κινητής υποδιαστολής του οποίου η ακέραια τιμή είναι κοντά αλλά όχι ίση με 10**20. Αν χρειάζεστε ακριβείς μεγάλους ακέραιους, κρατήστε τους ως ακέραιους σε όλη τη διαδρομή - μην τους δρομολογήσετε μέσω κινητής υποδιαστολής.

  • Παρενέργειες αναπαράστασης κινητής υποδιαστολής: είσοδοι όπως -6.725 / 0.025 (δείτε Παραδείγματα) δεν προσγειώνονται στον μαθηματικό ακέραιο που «θα έπρεπε». Χρησιμοποιήστε sprintf "%.0f" ή POSIX::floor/POSIX::ceil αν χρειάζεστε συμπεριφορά στρογγυλοποίησης που ανέχεται αυτό.

  • Άπειρα και NaN: η int('Inf') επιστρέφει Inf· η int('-Inf') επιστρέφει -Inf· η int('NaN') επιστρέφει NaN. Η int δεν έχει ακέραιο στον οποίο να αποκόψει, οπότε επιστρέφει την ειδική τιμή αμετάβλητη. Αυτό ταιριάζει με κάθε εναλλακτική (sprintf "%d", POSIX::floor, POSIX::ceil) - καμία τους δεν σας δίνει πεπερασμένο ακέραιο εδώ.

  • undef: η int(undef) επιστρέφει 0 και εκπέμπει προειδοποίηση Use of uninitialized value υπό use warnings.

  • Μη αριθμητικές συμβολοσειρές: η int("abc") επιστρέφει 0 και εκπέμπει Argument "abc" isn't numeric υπό use warnings. Συμβολοσειρά που ξεκινά με αριθμητικό πρόθεμα ("42abc") αποδίδει την ακέραια τιμή του προθέματος (42) με την ίδια προειδοποίηση - η int το κληρονομεί αυτό από τον τυπικό αριθμητικό εξαναγκασμό της Perl, όχι από κάποια προσαρμοσμένη ανάλυση.

  • Λογικές τιμές και dualvars: η int διαβάζει το αριθμητικό μισό. Η int(!!1) δίνει 1· η int(!!0) δίνει 0. Για dualvar του οποίου οι συμβολοσειριακές και αριθμητικές τιμές διαφωνούν, η int χρησιμοποιεί την αριθμητική πλευρά.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • abs - μέτρο χωρίς πρόσημο· συνδυάστε την με την int όταν θέλετε το αποκομμένο μέτρο ανεξάρτητα από πρόσημο

  • sprintf - η sprintf "%d", $x επίσης αποκόπτει προς το μηδέν, αλλά επιπλέον μορφοποιεί το αποτέλεσμα ως συμβολοσειρά· χρησιμοποιήστε την όταν θέλετε την αποκομμένη τιμή και μια συγκεκριμένη μορφή κειμένου

  • POSIX::floor - στρογγυλοποίηση προς το αρνητικό άπειρο· η floor(-3.9) είναι -4, που είναι αυτό που πραγματικά θέλουν τα περισσότερα μαθηματικά περιβάλλοντα (γραφικά, bucketing)

  • POSIX::ceil - στρογγυλοποίηση προς το θετικό άπειρο· η ceil(-3.1) είναι -3, η ceil(3.1) είναι 4· το κάτοπτρο της floor

  • POSIX::round - στρογγυλοποίηση στον πλησιέστερο ακέραιο, με τα μισά μακριά από το μηδέν· χρησιμοποιήστε την όταν θέλετε στατιστική στρογγυλοποίηση αντί για αποκοπή

  • sprintf με "%.0f" - στρογγυλοποίηση στον πλησιέστερο ακέραιο, με τα μισά σε άρτιο (τραπεζική στρογγυλοποίηση) στις περισσότερες πλατφόρμες· διακριτικά διαφορετική από την POSIX::round στις μέσες τιμές