sin#
Επιστρέφει το ημίτονο αριθμού δοθέντος σε ακτίνια.
Η sin είναι το τυπικό τριγωνομετρικό ημίτονο: παίρνει γωνία μετρημένη σε ακτίνια και επιστρέφει τον λόγο της απέναντι πλευράς προς την υποτείνουσα του αντίστοιχου ορθογωνίου τριγώνου. Αν παραλειφθεί το EXPR, η sin λειτουργεί στο $_. Το αποτέλεσμα είναι πάντα αριθμός κινητής υποδιαστολής στο κλειστό διάστημα [-1, 1].
Σύνοψη#
sin EXPR
sin
Τι επιστρέφεται#
Αριθμός κινητής υποδιαστολής διπλής ακρίβειας στο [-1, 1]. Η Perl προωθεί την κλήση στη ρουτίνα sin(3) C της πλατφόρμας, οπότε η ακρίβεια και η συμπεριφορά στρογγυλοποίησης ταιριάζουν με τη libm σας. Οι ειδικές τιμές ακολουθούν το IEEE 754: η sin(0) είναι ακριβώς 0, οι sin("inf") και sin("nan") είναι και οι δύο NaN.
Ακτίνια, όχι μοίρες#
Το μακράν πιο συνηθισμένο λάθος με την sin είναι το να της δίνετε μοίρες. Μια πλήρης στροφή είναι 2 * π ακτίνια, όχι 360. Μετατρέψτε μία φορά και κρατήστε τη μετατραμμένη τιμή:
use POSIX qw(acos);
my $pi = acos(-1); # π to full double precision
sub deg2rad { $_[0] * $pi / 180 }
print sin( deg2rad(30) ), "\n"; # 0.5
print sin( 30 ), "\n"; # -0.988031624092862 - wrong if you meant degrees
Το Math::Trigext εξάγει τις deg2rad και rad2deg αν προτιμάτε να μη γράψετε εσείς τη μετατροπή.
Παραδείγματα#
Η sin(π/2) είναι μαθηματικά ακριβώς 1, αλλά επειδή το π δεν είναι αναπαραστάσιμο σε δυαδική κινητή υποδιαστολή το υπολογιζόμενο αποτέλεσμα υπολείπεται κατά μερικά ulps:
use POSIX qw(acos);
my $pi = acos(-1);
printf "%.17f\n", sin($pi / 2); # 1.00000000000000000
printf "%.17f\n", sin($pi); # 0.00000000000000012 - not exactly 0
Αντιμετωπίστε κάθε τριγωνομετρικό αποτέλεσμα που «θα έπρεπε να είναι μηδέν» ως κατά προσέγγιση μηδέν. Συγκρίνετε με ανοχή, όχι με ==.
Μετατροπή μοιρών σε ακτίνια ενσωματωμένα, χωρίς εισαγωγή αρθρώματος. Το 3.14159 είναι ακριβές σε έξι ψηφία - εντάξει για γραφικές παραστάσεις, όχι για αριθμητική ανάλυση:
for my $deg (0, 30, 45, 60, 90) {
printf "sin(%2d°) = %+.4f\n",
$deg, sin($deg * 3.14159 / 180);
}
# sin( 0°) = +0.0000
# sin(30°) = +0.5000
# sin(45°) = +0.7071
# sin(60°) = +0.8660
# sin(90°) = +1.0000
Για εργασία που χρειάζεται πλήρη διπλή ακρίβεια, αντικαταστήστε το 3.14159 με acos(-1) ή atan2(1, 1) * 4.
Αριθμητική παράγωγος του sin με πεπερασμένες διαφορές. Ο συμμετρικός διαπολυτύπος δύο σημείων (f(x+h) - f(x-h)) / (2h) θα έπρεπε να ανακτά το cos(x):
my $x = 1.0;
my $h = 1e-6;
my $deriv = (sin($x + $h) - sin($x - $h)) / (2 * $h);
printf "derivative: %.10f\n", $deriv; # 0.5403023059
printf "cos(%.1f): %.10f\n", $x, cos($x);
Η επιλογή του $h είναι συμβιβασμός: πολύ μεγάλο και κυριαρχεί το σφάλμα αποκοπής, πολύ μικρό και η αλληλοεξουδετέρωση στην αφαίρεση καταστρέφει το αποτέλεσμα. Το 1e-6 είναι μια λογική προεπιλογή για διπλή ακρίβεια.
Διασχίστε τον μοναδιαίο κύκλο και εκτυπώστε τα (cos θ, sin θ) σε οκτώ ισαπέχουσες γωνίες:
use POSIX qw(acos);
my $pi = acos(-1);
for my $k (0 .. 7) {
my $theta = $k * $pi / 4;
printf "%.3f %+.3f %+.3f\n",
$theta, cos($theta), sin($theta);
}
Αντίστροφο ημίτονο (τόξο ημιτόνου) μέσω της ταυτότητας από το perlfunc:
sub asin { atan2( $_[0], sqrt(1 - $_[0] * $_[0]) ) }
print asin(0.5), "\n"; # 0.523598775598299 (= π/6)
Οριακές περιπτώσεις#
Τα μη αριθμητικά ορίσματα εξαναγκάζονται σε
0. Ηsin("hello")επιστρέφει0επειδή η συμβολοσειρά μετατρέπεται πρώτα αριθμητικά σε0. Υπόuse warningsαυτό παράγει προειδοποίησηArgument "hello" isn't numeric in sin. Επικυρώστε την είσοδο μεlooks_like_numberαπό τοScalar::Utilαν η πηγή δεν είναι έμπιστη.Τα πολύ μεγάλα ορίσματα χάνουν ακρίβεια. Η
sinπρώτα ανάγει το όρισμά της modulo2π, και για|x|της τάξης του1e16ο πλησιέστερος αναπαραστάσιμος double διαφέρει από τοxκατά περισσότερο απόπ. Το αποτέλεσμα είναι ακόμα αριθμός στο[-1, 1], αλλά είναι ουσιαστικά τυχαίο. Ανάγετε εσείς τη γωνία πριν την κλήση αν συσσωρεύετε φάση σε πολλές επαναλήψεις.Το
undefεξαναγκάζεται σε0και επιστρέφει0, με τη συνήθη προειδοποίησηuninitializedυπόuse warnings.Ειδικές τιμές IEEE: οι
sin("inf"),sin("-inf"), καιsin("nan")επιστρέφουν όλεςNaN. Συγκρίνετε με$result != $result(τη μόνη τιμή που δεν είναι ίση με τον εαυτό της) για να ανιχνεύσετεNaN, ή χρησιμοποιήστεPOSIX::isnan.Προεπιλεγμένο όρισμα. Η
sin;χωρίς όρισμα διαβάζει το$_. Μέσα σε βρόχοwhile (<>)αυτό λειτουργεί στην τρέχουσα γραμμή, που σχεδόν πάντα είναι bug.Καμία υποστήριξη μιγαδικών αριθμών στην ενσωματωμένη. Για μιγαδικά ορίσματα χρησιμοποιήστε το
Math::Complexext, που υπερφορτώνει τηνsinμέσω υπερφόρτωσης τελεστών:use Math::Complex; my $z = cplx(1, 2); print sin($z), "\n"; # 3.16577851321617+1.9596010414216i
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
cos- συνημίτονο γωνίας σε ακτίνια· η συνοδευτική συνάρτηση που χρησιμοποιείται συχνότερα μαζί με τηνsinatan2- τόξο εφαπτομένης δύο ορισμάτων, το συνηθισμένο δομικό στοιχείο για αντίστροφη τριγωνομετρία (asin,acos) σε καθαρή Perlsqrt- τετραγωνική ρίζα· εμφανίζεται στην κλασική ταυτότηταasinasin(x) = atan2(x, sqrt(1 - x*x))Math::Trigext -asin,acos,atan, υπερβολικές παραλλαγές,deg2rad/rad2deg, και βοηθητικά για μέγιστο κύκλοMath::Complexext - υπερφορτώνει τηνsin(και την υπόλοιπη τριγωνομετρική οικογένεια) για μιγαδικά ορίσματαPOSIX- εκθέτει τηνasinάμεσα, καθώς και τιςisnan/isinfγια ανίχνευση των μη πεπερασμένων αποτελεσμάτων που συζητούνται παραπάνω