sin#
Return the sine of a number given in radians.
sin is the standard trigonometric sine: it takes an angle measured
in radians and returns the ratio of the opposite side to the
hypotenuse of the corresponding right triangle. If EXPR is omitted,
sin operates on $_. The result is always a
floating-point number in the closed interval [-1, 1].
Synopsis#
sin EXPR
sin
What you get back#
A double-precision float in [-1, 1]. Perl forwards the call to the
platform’s C sin(3) routine, so the precision and rounding
behaviour match your libm. Special values follow IEEE 754: sin(0)
is exactly 0, sin("inf") and sin("nan") are both NaN.
Radians, not degrees#
The single most common mistake with sin is feeding it degrees. A
full turn is 2 * π radians, not 360. Convert once and keep the
converted value:
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 exports deg2rad and rad2deg if you would rather not
write the conversion yourself.
Examples#
sin(π/2) is mathematically exactly 1, but because π is not
representable in binary floating-point the computed result falls a
few ulps short:
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
Treat any “should be zero” trig result as approximately zero. Compare
with a tolerance, not with ==.
Degree-to-radian conversion inline, without pulling in a module.
3.14159 is accurate to six digits — fine for plotting, not for
numeric analysis:
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
For work that needs full double precision, replace 3.14159 with
acos(-1) or atan2(1, 1) * 4.
Numerical derivative of sin by finite differences. The symmetric
two-point formula (f(x+h) - f(x-h)) / (2h) should recover 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);
Picking $h is a trade-off: too large and truncation error
dominates, too small and subtraction cancellation destroys the
result. 1e-6 is a reasonable default for double precision.
Walk the unit circle and print (cos θ, sin θ) at eight evenly
spaced angles:
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);
}
Inverse sine (arcsine) via the identity from perlfunc:
sub asin { atan2( $_[0], sqrt(1 - $_[0] * $_[0]) ) }
print asin(0.5), "\n"; # 0.523598775598299 (= π/6)
Edge cases#
Non-numeric arguments coerce to
0.sin("hello")returns0because the string is numified to0first. Underuse warningsthis produces anArgument "hello" isn't numeric in sinwarning. Validate input withlooks_like_numberfromScalar::Utilif the source is untrusted.Very large arguments lose precision.
sinfirst reduces its argument modulo2π, and for|x|on the order of1e16the nearest representable double differs fromxby more thanπ. The result is still a number in[-1, 1], but it is essentially random. Reduce the angle yourself before the call if you are accumulating a phase over many iterations.undefcoerces to0and returns0, with the usualuninitializedwarning underuse warnings.IEEE specials:
sin("inf"),sin("-inf"), andsin("nan")all returnNaN. Compare with$result != $result(the only value not equal to itself) to detectNaN, or usePOSIX::isnan.Default argument.
sin;with no argument reads$_. Inside awhile (<>)loop this operates on the current line, which is almost always a bug.No complex-number support in the built-in. For complex arguments use
Math::Complexext, which overloadssinvia operator overloading:use Math::Complex; my $z = cplx(1, 2); print sin($z), "\n"; # 3.16577851321617+1.9596010414216i
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
cos— cosine of an angle in radians; the companion function most often used alongsidesinatan2— two-argument arctangent, the usual building block for inverse trig (asin,acos) in pure Perlsqrt— square root; appears in the classicalasinidentityasin(x) = atan2(x, sqrt(1 - x*x))Math::Trigext —asin,acos,atan, hyperbolic variants,deg2rad/rad2deg, and great-circle helpersMath::Complexext — overloadssin(and the rest of the trig family) for complex argumentsPOSIX— exposesasindirectly, plusisnan/isinffor detecting the non-finite results discussed above