Numeric functions

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") returns 0 because the string is numified to 0 first. Under use warnings this produces an Argument "hello" isn't numeric in sin warning. Validate input with looks_like_number from Scalar::Util if the source is untrusted.

  • Very large arguments lose precision. sin first reduces its argument modulo , and for |x| on the order of 1e16 the nearest representable double differs from x by 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.

  • undef coerces to 0 and returns 0, with the usual uninitialized warning under use warnings.

  • IEEE specials: sin("inf"), sin("-inf"), and sin("nan") all return NaN. Compare with $result != $result (the only value not equal to itself) to detect NaN, or use POSIX::isnan.

  • Default argument. sin; with no argument reads $_. Inside a while (<>) 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 overloads sin via 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 alongside sin

  • atan2 — two-argument arctangent, the usual building block for inverse trig (asin, acos) in pure Perl

  • sqrt — square root; appears in the classical asin identity asin(x) = atan2(x, sqrt(1 - x*x))

  • Math::Trigextasin, acos, atan, hyperbolic variants, deg2rad/rad2deg, and great-circle helpers

  • Math::Complexext — overloads sin (and the rest of the trig family) for complex arguments

  • POSIX — exposes asin directly, plus isnan/isinf for detecting the non-finite results discussed above